diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index 064ad0327b..a005a89562 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -74,6 +74,21 @@ stages: - stage: build displayName: Build jobs: + # Code check + - template: jobs/default-build.yml + parameters: + jobName: Code_check + jobDisplayName: Code check + agentOs: Windows + steps: + - powershell: ./eng/scripts/CodeCheck.ps1 -ci + displayName: Run eng/scripts/CodeCheck.ps1 + artifacts: + - name: Code_Check_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + # Build Windows (x64/x86) - template: jobs/default-build.yml parameters: @@ -99,11 +114,35 @@ stages: -arch x64 -pack -all - -NoBuildNative + -buildNative /bl:artifacts/log/build.x64.binlog $(_BuildArgs) displayName: Build x64 + # Build the x86 shared framework + # TODO: make it possible to build for one Windows architecture at a time + # This is going to actually build x86 native assets. See https://github.com/dotnet/aspnetcore/issues/7196 + - script: ./build.cmd + -ci + -arch x86 + -pack + -all + -buildNative + -noBuildJava + /p:OnlyPackPlatformSpecificPackages=true + /bl:artifacts/log/build.x86.binlog + $(_BuildArgs) + displayName: Build x86 + + # This is in a separate build step with -forceCoreMsbuild to workaround MAX_PATH limitations - https://github.com/Microsoft/msbuild/issues/53 + - script: .\src\SiteExtensions\build.cmd + -ci + -pack + -noBuildDeps + $(_BuildArgs) + condition: ne(variables['Build.Reason'], 'PullRequest') + displayName: Build SiteExtension + # This runs code-signing on all packages, zips, and jar files as defined in build/CodeSign.targets. If https://github.com/dotnet/arcade/issues/1957 is resolved, # consider running code-signing inline with the other previous steps. # Sign check is disabled because it is run in a separate step below, after installers are built. @@ -130,6 +169,16 @@ stages: /p:PublishInstallerBaseVersion=true displayName: Build Installers + # A few files must also go to the VS package feed. + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: NuGetCommand@2 + displayName: Push Visual Studio packages + inputs: + command: push + packagesToPush: 'artifacts/packages/**/VS.Redist.Common.AspNetCore.*.nupkg' + nuGetFeedType: external + publishFeedCredentials: 'DevDiv - VS package feed' + artifacts: - name: Windows_Logs path: artifacts/log/ @@ -138,6 +187,251 @@ stages: - name: Windows_Packages path: artifacts/packages/ + # Build Windows ARM + - template: jobs/default-build.yml + parameters: + codeSign: true + jobName: Windows_arm_build + jobDisplayName: "Build: Windows ARM" + agentOs: Windows + buildArgs: + -arch arm + -sign + -pack + -noBuildNodeJS + -noBuildJava + /bl:artifacts/log/build.win-arm.binlog + /p:DotNetSignType=$(_SignType) + /p:OnlyPackPlatformSpecificPackages=true + /p:AssetManifestFileName=aspnetcore-win-arm.xml + $(_BuildArgs) + $(_PublishArgs) + installNodeJs: false + installJdk: false + artifacts: + - name: Windows_arm_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: Windows_arm_Packages + path: artifacts/packages/ + + # Build MacOS + - template: jobs/default-build.yml + parameters: + jobName: MacOs_x64_build + jobDisplayName: "Build: macOS" + agentOs: macOs + buildArgs: + --pack + --all + --no-build-nodejs + --no-build-java + -p:OnlyPackPlatformSpecificPackages=true + -bl:artifacts/log/build.macos.binlog + -p:AssetManifestFileName=aspnetcore-MacOS_x64.xml + $(_BuildArgs) + $(_PublishArgs) + installNodeJs: false + installJdk: false + artifacts: + - name: MacOS_x64_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: MacOS_x64_Packages + path: artifacts/packages/ + - template: jobs/codesign-xplat.yml + parameters: + inputName: MacOS_x64 + + # Build Linux x64 + - template: jobs/default-build.yml + parameters: + jobName: Linux_x64_build + jobDisplayName: "Build: Linux x64" + agentOs: Linux + steps: + - script: ./build.sh + --ci + --arch x64 + --pack + --all + --no-build-nodejs + --no-build-java + -p:OnlyPackPlatformSpecificPackages=true + -bl:artifacts/log/build.linux-x64.binlog + $(_BuildArgs) + displayName: Run build.sh + - script: | + git clean -xfd src/**/obj/ + ./dockerbuild.sh bionic \ + --ci \ + --arch x64 \ + --build-installers \ + --no-build-deps \ + --no-build-nodejs \ + -p:OnlyPackPlatformSpecificPackages=true \ + -p:BuildRuntimeArchive=false \ + -p:LinuxInstallerType=deb \ + -bl:artifacts/log/build.deb.binlog \ + $(_BuildArgs) + displayName: Build Debian installers + - script: | + git clean -xfd src/**/obj/ + ./dockerbuild.sh rhel \ + --ci \ + --arch x64 \ + --build-installers \ + --no-build-deps \ + --no-build-nodejs \ + -p:OnlyPackPlatformSpecificPackages=true \ + -p:BuildRuntimeArchive=false \ + -p:LinuxInstallerType=rpm \ + -bl:artifacts/log/build.rpm.binlog \ + -p:AssetManifestFileName=aspnetcore-Linux_x64.xml \ + $(_BuildArgs) \ + $(_PublishArgs) + displayName: Build RPM installers + installNodeJs: false + installJdk: false + artifacts: + - name: Linux_x64_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: Linux_x64_Packages + path: artifacts/packages/ + - template: jobs/codesign-xplat.yml + parameters: + inputName: Linux_x64 + + # Build Linux ARM + - template: jobs/default-build.yml + parameters: + jobName: Linux_arm_build + jobDisplayName: "Build: Linux ARM" + agentOs: Linux + buildArgs: + --arch arm + --pack + --all + --no-build-nodejs + --no-build-java + -p:OnlyPackPlatformSpecificPackages=true + -bl:artifacts/log/build.linux-arm.binlog + -p:AssetManifestFileName=aspnetcore-Linux_arm.xml + $(_BuildArgs) + $(_PublishArgs) + installNodeJs: false + installJdk: false + artifacts: + - name: Linux_arm_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: Linux_arm_Packages + path: artifacts/packages/ + - template: jobs/codesign-xplat.yml + parameters: + inputName: Linux_arm + + # Build Linux ARM64 + - template: jobs/default-build.yml + parameters: + jobName: Linux_arm64_build + jobDisplayName: "Build: Linux ARM64" + agentOs: Linux + buildArgs: + --arch arm64 + --all + --pack + --no-build-nodejs + --no-build-java + -p:OnlyPackPlatformSpecificPackages=true + -bl:artifacts/log/build.arm64.binlog + -p:AssetManifestFileName=aspnetcore-Linux_arm64.xml + $(_BuildArgs) + $(_PublishArgs) + installNodeJs: false + installJdk: false + artifacts: + - name: Linux_arm64_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: Linux_arm64_Packages + path: artifacts/packages/ + - template: jobs/codesign-xplat.yml + parameters: + inputName: Linux_arm64 + + # Build Linux Musl x64 + - template: jobs/default-build.yml + parameters: + jobName: Linux_musl_x64_build + jobDisplayName: "Build: Linux Musl x64" + agentOs: Linux + buildScript: ./dockerbuild.sh alpine + buildArgs: + --ci + --arch x64 + --os-name linux-musl + --pack + --all + --no-build-nodejs + --no-build-java + -p:OnlyPackPlatformSpecificPackages=true + -bl:artifacts/log/build.musl.binlog + -p:AssetManifestFileName=aspnetcore-Linux_musl_x64.xml + $(_BuildArgs) + $(_PublishArgs) + installNodeJs: false + installJdk: false + artifacts: + - name: Linux_musl_x64_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: Linux_musl_x64_Packages + path: artifacts/packages/ + - template: jobs/codesign-xplat.yml + parameters: + inputName: Linux_musl_x64 + + # Build Linux Musl ARM64 + - template: jobs/default-build.yml + parameters: + jobName: Linux_musl_arm64_build + jobDisplayName: "Build: Linux Musl ARM64" + agentOs: Linux + buildScript: ./dockerbuild.sh ubuntu-alpine37 + buildArgs: + --ci + --arch arm64 + --os-name linux-musl + --pack + --all + --no-build-nodejs + --no-build-java + -p:OnlyPackPlatformSpecificPackages=true + -bl:artifacts/log/build.musl.binlog + -p:AssetManifestFileName=aspnetcore-Linux_musl_arm64.xml + $(_BuildArgs) + $(_PublishArgs) + installNodeJs: false + installJdk: false + artifacts: + - name: Linux_musl_arm64_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + - name: Linux_musl_arm64_Packages + path: artifacts/packages/ + - template: jobs/codesign-xplat.yml + parameters: + inputName: Linux_musl_arm64 + # Test jobs - template: jobs/default-build.yml parameters: @@ -164,7 +458,7 @@ stages: - name: Windows_Test_Dumps path: artifacts/dumps/ publishOnError: true - includeForks: false + includeForks: true - name: Windows_Test_Logs path: artifacts/log/ publishOnError: true @@ -192,7 +486,7 @@ stages: - name: Windows_Test_Templates_Dumps path: artifacts/dumps/ publishOnError: true - includeForks: false + includeForks: true - name: Windows_Test_Templates_Logs path: artifacts/log/ publishOnError: true @@ -274,15 +568,126 @@ stages: publishOnError: true includeForks: true +# Helix x64 + - template: jobs/default-build.yml + parameters: + condition: eq(variables['Build.Reason'], 'PullRequest') + jobName: Helix_x64 + jobDisplayName: 'Tests: Helix x64' + agentOs: Windows + timeoutInMinutes: 180 + steps: + - script: .\restore.cmd -ci + displayName: Restore + - script: .\build.cmd -ci -NoRestore -test -projects eng\helix\helix.proj /p:IsRequiredCheck=true /p:IsHelixJob=true /p:BuildAllProjects=true /p:BuildNative=false -bl + displayName: Run build.cmd helix target + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops + artifacts: + - name: Helix_logs + path: artifacts/log/ + publishOnError: true + includeForks: true + + - template: jobs/default-build.yml + parameters: + condition: ne(variables['Build.Reason'], 'PullRequest') + jobName: Helix_x64_daily + jobDisplayName: 'Tests: Helix x64 Daily' + agentOs: Windows + timeoutInMinutes: 180 + steps: + - script: .\restore.cmd -ci + displayName: Restore + - script: .\build.cmd -ci -NoRestore -test -projects eng\helix\helix.proj /p:IsHelixJob=true /p:IsHelixDaily=true /p:BuildAllProjects=true /p:BuildNative=true -bl + displayName: Run build.cmd helix target + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops + artifacts: + - name: Helix_logs + path: artifacts/log/ + publishOnError: true + includeForks: true + + # Helix ARM64 + - template: jobs/default-build.yml + parameters: + condition: ne(variables['Build.Reason'], 'PullRequest') + jobName: Helix_arm64_daily + jobDisplayName: "Tests: Helix ARM64 Daily" + agentOs: Linux + timeoutInMinutes: 180 + steps: + - script: ./restore.sh -ci + displayName: Restore + - script: ./build.sh -ci --arch arm64 -test --no-build-nodejs -projects $(Build.SourcesDirectory)/eng/helix/helix.proj /p:IsHelixJob=true /p:IsHelixDaily=true /p:BuildAllProjects=true /p:BuildNative=true -bl + displayName: Run build.sh helix arm64 target + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops + installNodeJs: false + artifacts: + - name: Helix_arm64_logs + path: artifacts/log/ + publishOnError: true + includeForks: true + + # Source build + - job: Source_Build + displayName: 'Test: Linux Source Build' + container: centos:7 + pool: + vmImage: 'ubuntu-16.04' + variables: + DotNetCoreSdkDir: $(Agent.ToolsDirectory)/dotnet + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: true + steps: + - script: | + source eng/common/native/common-library.sh + mkdir -p $HOME/bin + GetFile https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 $HOME/bin/jq + chmod +x $HOME/bin/jq + echo "##vso[task.prependpath]$HOME/bin" + displayName: Install jq + - script: ./eng/scripts/ci-source-build.sh --ci --configuration Release /p:BuildManaged=true /p:BuildNodeJs=false + displayName: Run ci-source-build.sh + - task: PublishBuildArtifacts@1 + displayName: Upload logs + condition: always() + continueOnError: true + inputs: + pathtoPublish: artifacts/log/ + artifactName: Source_Build_Logs + artifactType: Container + parallel: true + - task: PublishBuildArtifacts@1 + displayName: Upload package artifacts + # Only capture source build artifacts in PRs for the sake of inspecting + # changes that impact source-build. The artifacts from this build pipeline are never actually used. + condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) + inputs: + pathtoPublish: artifacts/packages/ + artifactName: Source_Build_Packages + artifactType: Container + parallel: true + # Publish to the BAR - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - template: /eng/common/templates/job/publish-build-assets.yml parameters: dependsOn: - Windows_build + - Windows_arm_build + - CodeSign_Xplat_MacOS_x64 + - CodeSign_Xplat_Linux_x64 + - CodeSign_Xplat_Linux_arm + - CodeSign_Xplat_Linux_arm64 + - CodeSign_Xplat_Linux_musl_x64 + - CodeSign_Xplat_Linux_musl_arm64 # In addition to the dependencies above, ensure the build was successful overall. + - Code_check - Linux_Test - MacOS_Test + - Source_Build - Windows_Templates_Test - Windows_Test pool: diff --git a/.azure/pipelines/devBuilds.yml b/.azure/pipelines/devBuilds.yml new file mode 100644 index 0000000000..61cb699a4e --- /dev/null +++ b/.azure/pipelines/devBuilds.yml @@ -0,0 +1,118 @@ +# +# See https://docs.microsoft.com/en-us/vsts/pipelines/yaml-schema for details on this file. +# + +# Configure which branches trigger builds +trigger: none + +# no PR builds +pr: none + +# Schedule this pipeline to run every midnight +schedules: +- cron: "0 8 * * *" + displayName: Daily midnight Dev builds + branches: + include: + - master + always: true + +stages: +- stage: build_components + displayName: Build Components + jobs: + # Build components on Windows (x64) + - template: jobs/default-build.yml + parameters: + codeSign: false + jobName: Windows_build + jobDisplayName: "Build: Components" + agentOs: Windows + steps: + - script: git submodule init + - script: git submodule update --recursive + - script: cd ./src/Components + - script: ./build.cmd + -ci + -arch x64 + /bl:artifacts/log/build.components.x64.binlog + displayName: Build x64 + artifacts: + - name: Windows_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + +- stage: build_servers + displayName: Build Servers + jobs: + # Build servers on Windows (x64) + - template: jobs/default-build.yml + parameters: + codeSign: false + jobName: Windows_build + jobDisplayName: "Build: Servers" + agentOs: Windows + steps: + - script: git submodule init + - script: git submodule update --recursive + - script: cd ./src/Servers + - script: ./build.cmd + -ci + -arch x64 + /bl:artifacts/log/build.servers.x64.binlog + displayName: Build x64 + artifacts: + - name: Windows_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + +- stage: build_project_templates + displayName: Build Project Templates + jobs: + # Build servers on Windows (x64) + - template: jobs/default-build.yml + parameters: + codeSign: false + jobName: Windows_build + jobDisplayName: "Build: Project Templates" + agentOs: Windows + steps: + - script: git submodule init + - script: git submodule update --recursive + - script: cd ./src/ProjectTemplates + - script: ./build.cmd + -ci + -arch x64 + /bl:artifacts/log/build.projectTemplates.x64.binlog + displayName: Build x64 + artifacts: + - name: Windows_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true + +- stage: build_all + displayName: Build Everything + jobs: + # Build servers on Windows (x64) + - template: jobs/default-build.yml + parameters: + codeSign: false + jobName: Windows_build + jobDisplayName: "Build: Everything" + agentOs: Windows + steps: + - script: git submodule init + - script: git submodule update --recursive + - script: ./build.cmd + -ci + -arch x64 + /bl:artifacts/log/build.all.x64.binlog + displayName: Build x64 + artifacts: + - name: Windows_Logs + path: artifacts/log/ + publishOnError: true + includeForks: true diff --git a/.azure/pipelines/jobs/default-build.yml b/.azure/pipelines/jobs/default-build.yml index d218c44531..add29afc05 100644 --- a/.azure/pipelines/jobs/default-build.yml +++ b/.azure/pipelines/jobs/default-build.yml @@ -81,7 +81,7 @@ jobs: enablePublishUsingPipelines: ${{ variables._PublishUsingPipelines }} enablePublishTestResults: true # publish test results to AzDO (populates AzDO Tests tab) enableTelemetry: true - helixRepo: aspnet/AspNetCore + helixRepo: dotnet/aspnetcore helixType: build.product/ workspace: clean: all @@ -236,3 +236,4 @@ jobs: testResultsFiles: '**/TEST-com.microsoft.signalr*.xml' buildConfiguration: $(BuildConfiguration) buildPlatform: $(AgentOsName) + mergeTestResults: true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 103c64248f..42b6a58971 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,9 +14,11 @@ /src/Hosting/ @tratcher @anurse /src/Http/ @tratcher @jkotalik @anurse /src/Middleware/ @tratcher @anurse -/src/ProjectTemplates/ @ryanbrandenburg +/src/Middleware/HttpsPolicy/ @jkotalik @anurse +/src/Middleware/Rewrite/ @jkotalik @anurse +# /src/ProjectTemplates/ @ryanbrandenburg /src/Security/ @tratcher @anurse /src/Servers/ @tratcher @jkotalik @anurse @halter73 -/src/Middleware/Rewrite @jkotalik @anurse -/src/Middleware/HttpsPolicy @jkotalik @anurse +/src/Shared/Http2/ @aspnet/http2 +/src/Shared/test/Shared.Tests/Http2/ @aspnet/http2 /src/SignalR/ @BrennanConroy @halter73 @anurse diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ed23a80be2..86f53b9a8a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,24 +3,34 @@ name: Bug report about: Create a report about something that is not working --- -### If you believe you have an issue that affects the security of the platform please do NOT create an issue and instead email your issue details to secure@microsoft.com. Your report may be eligible for our [bug bounty](https://technet.microsoft.com/en-us/mt764065.aspx) but ONLY if it is reported through email. + ### Describe the bug A clear and concise description of what the bug is. ### To Reproduce -Steps to reproduce the behavior: -1. Using this version of ASP.NET Core '...' -2. Run this code '....' -3. With these arguments '....' -4. See error + + +### Further technical details +- ASP.NET Core version +- Include the output of `dotnet --info` +- The IDE (VS / VS Code/ VS4Mac) you're running on, and it's version diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index d2dac5f2da..d7991eb1e0 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -3,6 +3,12 @@ name: Feature request about: Suggest an idea for this project --- + + ### Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Example: I am trying to do [...] but [...] diff --git a/.gitignore b/.gitignore index 8a2385174b..427adc7189 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ modules/ *.psess *.res *.snk +*.so *.suo *.tlog *.user @@ -40,3 +41,4 @@ launchSettings.json msbuild.ProjectImports.zip StyleCop.Cache UpgradeLog.htm +.idea \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 222522b092..238c74186d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,16 +3,16 @@ One of the easiest ways to contribute is to participate in discussions on GitHub issues. You can also contribute by submitting pull requests with code changes. ## General feedback and discussions? -Start a discussion on the [repository issue tracker](https://github.com/aspnet/AspNetCore/issues). +Start a discussion on the [repository issue tracker](https://github.com/dotnet/aspnetcore/issues). ## Bugs and feature requests? For non-security related bugs, log a new issue in the appropriate GitHub repository. Here are some of the most common repositories: * [Docs](https://github.com/aspnet/Docs) -* [AspNetCore](https://github.com/aspnet/AspNetCore) -* [Entity Framework Core](https://github.com/aspnet/EntityFrameworkCore) +* [AspNetCore](https://github.com/dotnet/aspnetcore) +* [Entity Framework Core](https://github.com/dotnet/efcore) * [Tooling](https://github.com/aspnet/Tooling) -* [Extensions](https://github.com/aspnet/Extensions) +* [Extensions](https://github.com/dotnet/extensions) Or browse the full list of repositories in the [aspnet](https://github.com/aspnet/) organization. @@ -31,8 +31,8 @@ Our team members also monitor several other discussion forums: We accept fixes and features! Here are some resources to help you get started on how to contribute code or new content. * Look at the [Contributor documentation](/docs/) to get started on building the source code on your own. -* ["Help wanted" issues](https://github.com/aspnet/AspNetCore/labels/help%20wanted) - these issues are up for grabs. Comment on an issue if you want to create a fix. -* ["Good first issue" issues](https://github.com/aspnet/AspNetCore/labels/good%20first%20issue) - we think these are a good for newcomers. +* ["Help wanted" issues](https://github.com/dotnet/aspnetcore/labels/help%20wanted) - these issues are up for grabs. Comment on an issue if you want to create a fix. +* ["Good first issue" issues](https://github.com/dotnet/aspnetcore/labels/good%20first%20issue) - we think these are a good for newcomers. ### Identifying the scale @@ -42,7 +42,7 @@ If you would like to contribute to one of our repositories, first identify the s You will need to sign a [Contributor License Agreement](https://cla.dotnetfoundation.org/) when submitting your pull request. To complete the Contributor License Agreement (CLA), you will need to follow the instructions provided by the CLA bot when you send the pull request. This needs to only be done once for any .NET Foundation OSS project. -If you don't know what a pull request is read this article: https://help.github.com/articles/using-pull-requests. Make sure the repository can build and all tests pass. Familiarize yourself with the project workflow and our coding conventions. The coding, style, and general engineering guidelines are published on the [Engineering guidelines](https://github.com/aspnet/AspNetCore/wiki/Engineering-guidelines) page. +If you don't know what a pull request is read this article: https://help.github.com/articles/using-pull-requests. Make sure the repository can build and all tests pass. Familiarize yourself with the project workflow and our coding conventions. The coding, style, and general engineering guidelines are published on the [Engineering guidelines](https://github.com/dotnet/aspnetcore/wiki/Engineering-guidelines) page. ### Tests diff --git a/Directory.Build.props b/Directory.Build.props index 2fe19bde83..e23fce5484 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@  $(MSBuildThisFileDirectory) - https://github.com/aspnet/AspNetCore + https://github.com/dotnet/aspnetcore git @@ -51,7 +51,7 @@ true - netcoreapp3.1 + netcoreapp5.0 @@ -61,6 +61,10 @@ $(WarningsNotAsErrors);CS1591 $(WarningsNotAsErrors);xUnit1004 + + $(NoWarn);NU5131 + + $(NoWarn);NU5048 @@ -104,6 +108,7 @@ win osx linux + $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()) x64 $(TargetOsName)-$(TargetArchitecture) diff --git a/NuGet.config b/NuGet.config index d62ece6b60..11689b03fa 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,22 +3,16 @@ - - + - - - - - - - + + + - diff --git a/README.md b/README.md index 4b954c6076..4c2e975c42 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ASP.NET Core ============ -ASP.NET Core is an open-source and cross-platform framework for building modern cloud based internet connected applications, such as web apps, IoT apps and mobile backends. ASP.NET Core apps can run on .NET Core or on the full .NET Framework. It was architected to provide an optimized development framework for apps that are deployed to the cloud or run on-premises. It consists of modular components with minimal overhead, so you retain flexibility while constructing your solutions. You can develop and run your ASP.NET Core apps cross-platform on Windows, Mac and Linux. [Learn more about ASP.NET Core](https://docs.microsoft.com/aspnet/core/). +ASP.NET Core is an open-source and cross-platform framework for building modern cloud based internet connected applications, such as web apps, IoT apps and mobile backends. ASP.NET Core apps run on [.NET Core](https://dot.net), a free, cross-platform and open-source application runtime. It was architected to provide an optimized development framework for apps that are deployed to the cloud or run on-premises. It consists of modular components with minimal overhead, so you retain flexibility while constructing your solutions. You can develop and run your ASP.NET Core apps cross-platform on Windows, Mac and Linux. [Learn more about ASP.NET Core](https://docs.microsoft.com/aspnet/core/). ## Get Started @@ -9,6 +9,8 @@ Follow the [Getting Started](https://docs.microsoft.com/aspnet/core/getting-star Also check out the [.NET Homepage](https://www.microsoft.com/net) for released versions of .NET, getting started guides, and learning resources. +See the [Issue Management Policies](https://github.com/dotnet/aspnetcore/blob/anurse/issue-policies/docs/IssueManagementPolicies.md) document for more information on how we handle incoming issues. + ## How to Engage, Contribute, and Give Feedback Some of the best ways to contribute are to try things out, file issues, join in design conversations, @@ -17,7 +19,7 @@ and make pull-requests. * [Download our latest daily builds](./docs/DailyBuilds.md) * Follow along with the development of ASP.NET Core: * [Community Standup](https://live.asp.net): The community standup is held every week and streamed live to YouTube. You can view past standups in the linked playlist. - * [Roadmap](https://github.com/aspnet/AspNetCore/wiki/Roadmap): The schedule and milestone themes for ASP.NET Core. + * [Roadmap](https://github.com/dotnet/aspnetcore/wiki/Roadmap): The schedule and milestone themes for ASP.NET Core. * [Build ASP.NET Core source code](./docs/BuildFromSource.md) * Check out the [contributing](CONTRIBUTING.md) page to see the best places to log issues and start discussions. @@ -30,8 +32,8 @@ Security issues and bugs should be reported privately, via email, to the Microso These are some other repos for related projects: * [Documentation](https://github.com/aspnet/Docs) - documentation sources for https://docs.microsoft.com/aspnet/core/ -* [Entity Framework Core](https://github.com/aspnet/EntityFrameworkCore) - data access technology -* [Extensions](https://github.com/aspnet/Extensions) - Logging, configuration, dependency injection, and more. +* [Entity Framework Core](https://github.com/dotnet/efcore) - data access technology +* [Extensions](https://github.com/dotnet/extensions) - Logging, configuration, dependency injection, and more. ## Code of conduct diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt index 81fadeae22..99d1e37721 100644 --- a/THIRD-PARTY-NOTICES.txt +++ b/THIRD-PARTY-NOTICES.txt @@ -189,3 +189,31 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License notice for corefx + +------------------------------------------------ + +The MIT License (MIT) + +Copyright (c) .NET Foundation and Contributors + +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/build.ps1 b/build.ps1 index c515a84af5..8f36452cc2 100644 --- a/build.ps1 +++ b/build.ps1 @@ -93,7 +93,7 @@ Running tests. build.ps1 -test .LINK -Online version: https://github.com/aspnet/AspNetCore/blob/master/docs/BuildFromSource.md +Online version: https://github.com/dotnet/aspnetcore/blob/master/docs/BuildFromSource.md #> [CmdletBinding(PositionalBinding = $false, DefaultParameterSetName='Groups')] param( diff --git a/docs/BuildFromSource.md b/docs/BuildFromSource.md index 5cc74a5f9d..55300d6e39 100644 --- a/docs/BuildFromSource.md +++ b/docs/BuildFromSource.md @@ -1,11 +1,11 @@ Build ASP.NET Core from Source ============================== -Building ASP.NET Core from source allows you tweak and customize ASP.NET Core, and to contribute your improvements back to the project. +Building ASP.NET Core from source allows you to tweak and customize ASP.NET Core, and to contribute your improvements back to the project. -See https://github.com/aspnet/AspNetCore/labels/area-infrastructure for known issues and to track ongoing work. +See https://github.com/dotnet/aspnetcore/labels/area-infrastructure for known issues and to track ongoing work. -## Install pre-requistes +## Install pre-requisites ### Windows @@ -44,11 +44,11 @@ Building ASP.NET Core on macOS or Linux requires: ## Clone the source code -ASP.NET Core uses git submodules to include source from a few other projects. +ASP.NET Core uses git submodules to include the source from a few other projects. For a new copy of the project, run: ``` -git clone --recursive https://github.com/aspnet/AspNetCore +git clone --recursive https://github.com/dotnet/aspnetcore ``` To update an existing copy, run: @@ -64,19 +64,19 @@ Before opening our .sln files in Visual Studio or VS Code, you need to perform t ``` .\restore.cmd ``` - This will download required tools and build the entire repository once. At that point, you should be able to open .sln files to work on the projects you care about. + This will download the required tools and build the entire repository once. At that point, you should be able to open .sln files to work on the projects you care about. > :bulb: Pro tip: you will also want to run this command after pulling large sets of changes. On the master branch, we regularly update the versions of .NET Core SDK required to build the repo. > You will need to restart Visual Studio every time we update the .NET Core SDK. -2. Use the `startvs.cmd` script to open Visual Studio .sln files. This script first sets required environment variables. +2. Use the `startvs.cmd` script to open Visual Studio .sln files. This script first sets the required environment variables. ### Solution files We don't have a single .sln file for all of ASP.NET Core because Visual Studio doesn't currently handle projects of this scale. Instead, we have many .sln files which include a sub-set of projects. These principles guide how we create and manage .slns: -1. Solution files are not used by CI or command line build scripts. They are for meant for use by developers only. +1. Solution files are not used by CI or command line build scripts. They are meant for use by developers only. 2. Solution files group together projects which are frequently edited at the same time. 3. Can't find a solution that has the projects you care about? Feel free to make a PR to add a new .sln file. @@ -91,7 +91,7 @@ Opening solution files and building may produce an error code CS0006 with a mess The cause of this problem is that the solution you are using does not include the project that produces this .dll. This most often occurs after we have added new projects to the repo, but failed to update our .sln files to include the new project. In some cases, it is sometimes the intended behavior of the .sln which has been crafted to only include a subset of projects. **You can fix this in one of two ways** -1. Build the project on command line. In most cases, running `build.cmd` on command line solve this problem. +1. Build the project on command line. In most cases, running `build.cmd` on command line solves this problem. 2. Update the solution to include the missing project. You can either do this one by one using `dotnet sln` ``` dotnet sln add C:\src\AspNetCore\src\Hosting\Abstractions\src\Microsoft.AspNetCore.Hosting.Abstractions.csproj @@ -139,7 +139,7 @@ On macOS/Linux: ./build.sh ``` -By default, all of the C# projects are built. Some C# projects requires NodeJS to be installed to compile JavaScript assets which are then checked in as source. If NodeJS is detected on the path, the NodeJS projects will be compiled as part of building C# projects. If NodeJS is not detected on the path, the JavaScript assets checked in previously will be used instead. To disable building NodeJS projects, specify /p:BuildNodeJs=false on the command line. +By default, all of the C# projects are built. Some C# projects require NodeJS to be installed to compile JavaScript assets which are then checked in as source. If NodeJS is detected on the path, the NodeJS projects will be compiled as part of building C# projects. If NodeJS is not detected on the path, the JavaScript assets checked in previously will be used instead. To disable building NodeJS projects, specify /p:BuildNodeJs=false on the command line. ### Using `dotnet` on command line in this repo diff --git a/docs/DailyBuilds.md b/docs/DailyBuilds.md index 7e727df9e4..6c0c734bf8 100644 --- a/docs/DailyBuilds.md +++ b/docs/DailyBuilds.md @@ -13,13 +13,7 @@ If you want to download the latest daily build and use it in a project, then you - - - - - - - + diff --git a/docs/IssueManagementPolicies.md b/docs/IssueManagementPolicies.md new file mode 100644 index 0000000000..e71c969938 --- /dev/null +++ b/docs/IssueManagementPolicies.md @@ -0,0 +1,27 @@ +# Issue Management Policies + +We have a lot of issue traffic to manage, so we have a few policies in place to help us do that. This is a brief summary of some of the policies we have in place and the justification for them. + +## Commenting on closed issues + +In general, we recommend you open a new issue if you have a bug, feature request, or question to discuss. If you find a closed issue that is related, open a *new issue* and link to the closed issue rather than posting on the closed issue. Closed issues don't appear in our triage process, so only the people who have been active on the original thread will be notified of your comment. A new issue will get more attention from the team. + +*In general* we don't mind getting duplicate issues. It's easier for us to close duplicate issues than to discuss multiple root causes on a single issue! We may close your issue as a duplicate if we determine it has the same root cause as another. Don't worry! It's not a waste of our time! + +## Needs Author Feedback + +If a contributor reviews an issue and determines that more information is needed from the author, they will post a comment requesting that information and apply the `Needs: Author Feedback` label. This label indicates that the author needs to post a response in order for us to continue investigating the issue. + +If the author does not post a response within **7 days**, the issue will be automatically closed. If the author responds within **7 days** after the issue is closed, the issue will be automatically re-opened. We recognize that you may not be able to respond immediately to our requests, we're happy to hear from you whenever you're able to provide the new information. + +## Duplicate issues + +If we determine that the issue is a duplicate of another, we will label it with the `Resolution: Duplicate` label. The issue will be automatically closed in 1 day of inactivity. + +## Answered questions + +If we determine that the issue is a question and have posted an answer, we will label it with the `Resolution: Answered` label. The issue will be automatically closed in 1 day of inactivity. + +## Locking closed issues + +After an issue has been closed and had no activity for **30 days** it will be automatically locked as *resolved*. This is done in order to reduce confusion as to where to post new comments. If you are still encountering the problem reported in an issue, or have a related question or bug report, feel free to open a *new issue* and link to the original (now locked) issue! diff --git a/docs/ReferenceAssemblies.md b/docs/ReferenceAssemblies.md index 1ef20699e6..593682a29e 100644 --- a/docs/ReferenceAssemblies.md +++ b/docs/ReferenceAssemblies.md @@ -22,4 +22,4 @@ Set `false` in the implementation ( ### Regenerate reference assemblies for all projects -Run `.\eng\scripts\GenerateReferenceAssemblies.ps1` from repository root. +Run `.\eng\scripts\GenerateReferenceAssemblies.ps1` from repository root. Make sure you've run `.\restore.cmd` first. diff --git a/docs/ReferenceResolution.md b/docs/ReferenceResolution.md index 8f1fe70675..0c5d231bef 100644 --- a/docs/ReferenceResolution.md +++ b/docs/ReferenceResolution.md @@ -69,7 +69,7 @@ Steps for adding a new package dependency to an existing project. Let's say I'm If you don't know the commit hash of the source code used to produce "0.0.1-beta-1", you can use `000000` as a placeholder for `Sha` as its value is unimportant and will be updated the next time the bot runs. - If the new dependency comes from dotnet/CoreFx, dotnet/code-setup or aspnet/Extensions, add a + If the new dependency comes from dotnet/CoreFx, dotnet/code-setup or dotnet/extensions, add a `CoherentParentDependency` attribute to the `` element as shown below. This example indicates the dotnet/CoreFx dependency version should be determined based on the build that produced the chosen Microsoft.NETCore.App. That is, the dotnet/CoreFx dependency and Microsoft.NETCore.App should be @@ -82,7 +82,7 @@ Steps for adding a new package dependency to an existing project. Let's say I'm ``` The attribute value should be `"Microsoft.Extensions.Logging"` for dotnet/core-setup dependencies and - `"Microsoft.CodeAnalysis.Razor"` for aspnet/Extensions dependencies. + `"Microsoft.CodeAnalysis.Razor"` for dotnet/extensions dependencies. ## Example: make a breaking change to references diff --git a/docs/Submodules.md b/docs/Submodules.md index 8d24c40ff5..18e0a87caf 100644 --- a/docs/Submodules.md +++ b/docs/Submodules.md @@ -9,7 +9,7 @@ For full information, see the [official docs for git submodules](https://git-scm ## Fundamental concept -The parent repo (aspnet/AspNetCore) stores two pieces of info about each submodule. +The parent repo (dotnet/aspnetcore) stores two pieces of info about each submodule. 1. Where to clone the submodule from. This is stored in the .gitmodules file 2. The commit hash of the submodule to use. @@ -22,7 +22,7 @@ Other info may appear in the .gitmodules file, but it is only used when attempti By default, submodules will not be present. Use `--recursive` to clone all submodules. - git clone https://github.com/aspnet/AspNetCore.git --recursive + git clone https://github.com/dotnet/aspnetcore.git --recursive If you have already cloned, run this to initialize all submodules. @@ -72,7 +72,7 @@ that contains the new commit. git add modules/KestrelhttpServer/ git commit -m "Update Kestrel to latest version" -## PowerShell is slow in aspnet/AspNetCore +## PowerShell is slow in dotnet/aspnetcore Many users have post-git, and extension that shows git status on the prompt line. Because `git status` with submodules on Windows is very slow, it can make PowerShell unbearable to use. diff --git a/eng/Build.props b/eng/Build.props index 17c9848f83..450f8731ad 100644 --- a/eng/Build.props +++ b/eng/Build.props @@ -50,11 +50,6 @@ " /> - - - $(RepoRoot)src\Components\**\*.csproj;$(RepoRoot)src\ProjectTemplates\**\*.csproj - - diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 2e11857b1b..097673484f 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -23,6 +23,7 @@ and are generated based on the last package release. + diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props index 350c026a7d..494a9a560a 100644 --- a/eng/ProjectReferences.props +++ b/eng/ProjectReferences.props @@ -63,6 +63,7 @@ + diff --git a/eng/SharedFramework.External.props b/eng/SharedFramework.External.props index 8fdebc787d..5c0c46740e 100644 --- a/eng/SharedFramework.External.props +++ b/eng/SharedFramework.External.props @@ -7,7 +7,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e93f24e28b..dbdb150bcd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,437 +13,429 @@ https://github.com/aspnet/Blazor 9ff01af4257317a90b64959fe1c87aef3da4a36f - - https://github.com/aspnet/AspNetCore-Tooling - abd3c17b317dbe455b18a4f5937c43e0fc7a2944 + + https://github.com/dotnet/aspnetcore-tooling + bb392859668ac4944acffb10c79ee62831ee0804 - - https://github.com/aspnet/AspNetCore-Tooling - abd3c17b317dbe455b18a4f5937c43e0fc7a2944 + + https://github.com/dotnet/aspnetcore-tooling + bb392859668ac4944acffb10c79ee62831ee0804 - - https://github.com/aspnet/AspNetCore-Tooling - abd3c17b317dbe455b18a4f5937c43e0fc7a2944 + + https://github.com/dotnet/aspnetcore-tooling + bb392859668ac4944acffb10c79ee62831ee0804 - - https://github.com/aspnet/AspNetCore-Tooling - abd3c17b317dbe455b18a4f5937c43e0fc7a2944 + + https://github.com/dotnet/aspnetcore-tooling + bb392859668ac4944acffb10c79ee62831ee0804 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - + https://github.com/aspnet/EntityFrameworkCore - 82c6ea483d3a17393dad5986df9a8eef89ddcd07 + e37a6be067ab62da7fe9b33b93faaa90ed829237 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - - https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 - - + https://github.com/dotnet/core-setup - 65f04fb6db7a5e198d05dbebd5c4ad21eb018f89 + 6fab00563d09dca0d2b777a4f0dbda59d19c8546 - + https://github.com/dotnet/core-setup - 65f04fb6db7a5e198d05dbebd5c4ad21eb018f89 + 6fab00563d09dca0d2b777a4f0dbda59d19c8546 - + https://github.com/dotnet/core-setup - 65f04fb6db7a5e198d05dbebd5c4ad21eb018f89 + 6fab00563d09dca0d2b777a4f0dbda59d19c8546 - + https://github.com/dotnet/core-setup - 7d57652f33493fa022125b7f63aad0d70c52d810 + 6fab00563d09dca0d2b777a4f0dbda59d19c8546 - + https://github.com/dotnet/core-setup - f3f2dd583fffa254015fc21ff0e45784b333256d + 6fab00563d09dca0d2b777a4f0dbda59d19c8546 - - https://github.com/dotnet/core-setup - 65f04fb6db7a5e198d05dbebd5c4ad21eb018f89 - - - https://github.com/aspnet/Extensions - 4e1be2fb546751c773968d7b40ff7f4b62887153 + + https://github.com/dotnet/corefx + 4ac4c0367003fe3973a3648eb0715ddb0e3bbcea - + https://github.com/dotnet/corefx - 0f7f38c4fd323b26da10cce95f857f77f0f09b48 + 475778fa982064e26a8b3a5d7545112f6586ac61 - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - + https://github.com/dotnet/arcade - 99c6b59a8afff97fe891341b39abe985f1d3c565 + 48bae09d7d8ec0e6879fe2b8d08872cd87f084ca - + https://github.com/dotnet/arcade - 99c6b59a8afff97fe891341b39abe985f1d3c565 + 48bae09d7d8ec0e6879fe2b8d08872cd87f084ca - + https://github.com/dotnet/arcade - 99c6b59a8afff97fe891341b39abe985f1d3c565 + 48bae09d7d8ec0e6879fe2b8d08872cd87f084ca - - https://github.com/aspnet/Extensions - 1c5c7777ea9a19d54ab67ec1521665c99460efc5 + + https://github.com/dotnet/extensions + 1513ad0854b32d08f86acd4cd25225af556c2c81 - + https://github.com/dotnet/roslyn - 82f2e2541478e239dc4b04f231e90dc2b3dcb422 + d2bd58c62f9104d66f415141a1a27b665c78690c diff --git a/eng/Versions.props b/eng/Versions.props index d2e01e6ef5..f7c177b878 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -6,24 +6,22 @@ --> - 3 - 1 + 5 + 0 0 - 3 + 1 - true + false release - true - false - preview$(PreReleasePreviewNumber) - Preview $(PreReleasePreviewNumber) + alpha + Alpha $(PreReleaseVersionIteration) $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion) false true @@ -62,117 +60,117 @@ --> - 1.0.0-beta.19577.5 + 5.0.0-beta.20058.1 - 3.4.0-beta4-19569-03 + 3.5.0-beta1-19606-04 - 3.1.1-servicing.19575.1 - 3.1.1-servicing.19576.9 - 3.1.0 - 3.1.1-servicing.19575.1 - 2.1.0 + 5.0.0-alpha.1.19562.8 + 5.0.0-alpha.1.19562.8 + 5.0.0-alpha.1.19562.8 + 5.0.0-alpha.1.19562.8 + 2.1.0-alpha.1.19562.8 - 1.1.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 1.8.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 - 4.7.0 + 1.0.0 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 + 5.0.0-alpha.1.19556.7 - 3.1.0 - + 5.0.0-alpha.1.19556.7 + 3.1.0-preview4.19578.1 - - 3.1.0-rtm.19575.5 - 3.1.0-rtm.19575.5 - 3.1.0-rtm.19575.5 - 3.1.0-rtm.19575.5 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0-rtm.19575.5 - 3.1.0-rtm.19575.5 - 3.1.0 - 3.1.0-rtm.19565.4 - 3.1.0 - 3.1.0-preview4.19575.5 - - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - 3.1.0 - - 3.1.0-rtm.19573.1 - 3.1.0-rtm.19573.1 - 3.1.0-rtm.19573.1 - 3.1.0-rtm.19573.1 + + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-alpha.1.20059.4 + 5.0.0-preview3.1.20059.4 + + 5.0.0-alpha.1.19602.5 + 5.0.0-alpha.1.19602.5 + 5.0.0-alpha.1.19602.5 + 5.0.0-alpha.1.19602.5 + 5.0.0-alpha.1.19602.5 + 5.0.0-alpha.1.19602.5 + 5.0.0-alpha.1.19602.5 + + 5.0.0-alpha.1.20059.7 + 5.0.0-alpha.1.20059.7 + 5.0.0-alpha.1.20059.7 + 5.0.0-alpha.1.20059.7 - + - 3.1 + 5.0 @@ -16,7 +16,7 @@ @@ -25,12 +25,7 @@ - - - $(MicrosoftNETCorePlatformsPackageVersion) - - - + + + + + + + diff --git a/eng/common/CheckSymbols.ps1 b/eng/common/CheckSymbols.ps1 index b8d84607b8..5442eff386 100644 --- a/eng/common/CheckSymbols.ps1 +++ b/eng/common/CheckSymbols.ps1 @@ -5,11 +5,12 @@ param( ) Add-Type -AssemblyName System.IO.Compression.FileSystem +. $PSScriptRoot\pipeline-logging-functions.ps1 function FirstMatchingSymbolDescriptionOrDefault { param( [string] $FullPath, # Full path to the module that has to be checked - [string] $TargetServerParam, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols + [string] $TargetServerParameter, # Parameter to pass to `Symbol Tool` indicating the server to lookup for symbols [string] $SymbolsPath ) @@ -21,36 +22,36 @@ function FirstMatchingSymbolDescriptionOrDefault { # checking and which type of file was uploaded. # The file itself is returned - $SymbolPath = $SymbolsPath + "\" + $FileName + $SymbolPath = $SymbolsPath + '\' + $FileName # PDB file for the module - $PdbPath = $SymbolPath.Replace($Extension, ".pdb") + $PdbPath = $SymbolPath.Replace($Extension, '.pdb') # PDB file for R2R module (created by crossgen) - $NGenPdb = $SymbolPath.Replace($Extension, ".ni.pdb") + $NGenPdb = $SymbolPath.Replace($Extension, '.ni.pdb') # DBG file for a .so library - $SODbg = $SymbolPath.Replace($Extension, ".so.dbg") + $SODbg = $SymbolPath.Replace($Extension, '.so.dbg') # DWARF file for a .dylib - $DylibDwarf = $SymbolPath.Replace($Extension, ".dylib.dwarf") + $DylibDwarf = $SymbolPath.Replace($Extension, '.dylib.dwarf') - .\dotnet-symbol.exe --symbols --modules --windows-pdbs $TargetServerParam $FullPath -o $SymbolsPath | Out-Null + .\dotnet-symbol.exe --symbols --modules --windows-pdbs $TargetServerParameter $FullPath -o $SymbolsPath | Out-Null if (Test-Path $PdbPath) { - return "PDB" + return 'PDB' } elseif (Test-Path $NGenPdb) { - return "NGen PDB" + return 'NGen PDB' } elseif (Test-Path $SODbg) { - return "DBG for SO" + return 'DBG for SO' } elseif (Test-Path $DylibDwarf) { - return "Dwarf for Dylib" + return 'Dwarf for Dylib' } elseif (Test-Path $SymbolPath) { - return "Module" + return 'Module' } else { return $null @@ -68,7 +69,7 @@ function CountMissingSymbols { } # Extensions for which we'll look for symbols - $RelevantExtensions = @(".dll", ".exe", ".so", ".dylib") + $RelevantExtensions = @('.dll', '.exe', '.so', '.dylib') # How many files are missing symbol information $MissingSymbols = 0 @@ -76,7 +77,7 @@ function CountMissingSymbols { $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath) $PackageGuid = New-Guid $ExtractPath = Join-Path -Path $ExtractPath -ChildPath $PackageGuid - $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath "Symbols" + $SymbolsPath = Join-Path -Path $ExtractPath -ChildPath 'Symbols' [System.IO.Compression.ZipFile]::ExtractToDirectory($PackagePath, $ExtractPath) @@ -86,31 +87,31 @@ function CountMissingSymbols { Get-ChildItem -Recurse $ExtractPath | Where-Object {$RelevantExtensions -contains $_.Extension} | ForEach-Object { - if ($_.FullName -Match "\\ref\\") { + if ($_.FullName -Match '\\ref\\') { Write-Host "`t Ignoring reference assembly file" $_.FullName return } - $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--microsoft-symbol-server" $SymbolsPath - $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault $_.FullName "--internal-server" $SymbolsPath + $SymbolsOnMSDL = FirstMatchingSymbolDescriptionOrDefault -FullPath $_.FullName -TargetServerParameter '--microsoft-symbol-server' -SymbolsPath $SymbolsPath + $SymbolsOnSymWeb = FirstMatchingSymbolDescriptionOrDefault -FullPath $_.FullName -TargetServerParameter '--internal-server' -SymbolsPath $SymbolsPath Write-Host -NoNewLine "`t Checking file" $_.FullName "... " if ($SymbolsOnMSDL -ne $null -and $SymbolsOnSymWeb -ne $null) { - Write-Host "Symbols found on MSDL (" $SymbolsOnMSDL ") and SymWeb (" $SymbolsOnSymWeb ")" + Write-Host "Symbols found on MSDL (${$SymbolsOnMSDL}) and SymWeb (${$SymbolsOnSymWeb})" } else { $MissingSymbols++ if ($SymbolsOnMSDL -eq $null -and $SymbolsOnSymWeb -eq $null) { - Write-Host "No symbols found on MSDL or SymWeb!" + Write-Host 'No symbols found on MSDL or SymWeb!' } else { if ($SymbolsOnMSDL -eq $null) { - Write-Host "No symbols found on MSDL!" + Write-Host 'No symbols found on MSDL!' } else { - Write-Host "No symbols found on SymWeb!" + Write-Host 'No symbols found on SymWeb!' } } } @@ -129,26 +130,26 @@ function CheckSymbolsAvailable { Get-ChildItem "$InputPath\*.nupkg" | ForEach-Object { $FileName = $_.Name - + # These packages from Arcade-Services include some native libraries that # our current symbol uploader can't handle. Below is a workaround until # we get issue: https://github.com/dotnet/arcade/issues/2457 sorted. - if ($FileName -Match "Microsoft\.DotNet\.Darc\.") { + if ($FileName -Match 'Microsoft\.DotNet\.Darc\.') { Write-Host "Ignoring Arcade-services file: $FileName" Write-Host return } - elseif ($FileName -Match "Microsoft\.DotNet\.Maestro\.Tasks\.") { + elseif ($FileName -Match 'Microsoft\.DotNet\.Maestro\.Tasks\.') { Write-Host "Ignoring Arcade-services file: $FileName" Write-Host return } - + Write-Host "Validating $FileName " $Status = CountMissingSymbols "$InputPath\$FileName" if ($Status -ne 0) { - Write-Error "Missing symbols for $Status modules in the package $FileName" + Write-PipelineTelemetryError -Category 'CheckSymbols' -Message "Missing symbols for $Status modules in the package $FileName" } Write-Host diff --git a/eng/common/PublishToSymbolServers.proj b/eng/common/PublishToSymbolServers.proj index 5d55e312b0..311e2bbe0f 100644 --- a/eng/common/PublishToSymbolServers.proj +++ b/eng/common/PublishToSymbolServers.proj @@ -37,6 +37,8 @@ 3650 true + true + true false @@ -56,7 +58,7 @@ DryRun="false" ConvertPortablePdbsToWindowsPdbs="false" PdbConversionTreatAsWarning="" - Condition="$(PublishToSymbolServer)"/> + Condition="$(PublishToSymbolServer) and $(PublishToMSDL)"/> git commit --> git push -Write-Host "git add ." -git add . -if ($LASTEXITCODE -ne 0) { - Write-Error "Git add failed with exit code $LASTEXITCODE." -} -Write-Host "git -c user.email=`"dn-bot@microsoft.com`" -c user.name=`"Dotnet Bot`" commit -m `"$PushReason for $Repository/$BranchName`"" -git -c user.email="dn-bot@microsoft.com" -c user.name="Dotnet Bot" commit -m "$PushReason for $Repository/$BranchName" -if ($LASTEXITCODE -ne 0) { - Write-Error "Git commit failed with exit code $LASTEXITCODE." -} -Write-Host "git push" -git push -if ($LASTEXITCODE -ne 0) { - Write-Error "Git push failed with exit code $LASTEXITCODE." -} + # We create the temp directory where we'll store the sdl-config repository + $sdlDir = Join-Path $env:TEMP 'sdl' + if (Test-Path $sdlDir) { + Remove-Item -Force -Recurse $sdlDir + } -# Return to the original directory -Pop-Location \ No newline at end of file + Write-Host "git clone https://dnceng:`$AzureDevOpsAccessToken@dev.azure.com/dnceng/internal/_git/sdl-tool-cfg $sdlDir" + git clone https://dnceng:$AzureDevOpsAccessToken@dev.azure.com/dnceng/internal/_git/sdl-tool-cfg $sdlDir + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Git clone failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + # We copy the .gdn folder from our local run into the git repository so it can be committed + $sdlRepositoryFolder = Join-Path (Join-Path (Join-Path $sdlDir $Repository) $BranchName) '.gdn' + if (Get-Command Robocopy) { + Robocopy /S $GdnFolder $sdlRepositoryFolder + } else { + rsync -r $GdnFolder $sdlRepositoryFolder + } + # cd to the sdl-config directory so we can run git there + Push-Location $sdlDir + # git add . --> git commit --> git push + Write-Host 'git add .' + git add . + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Git add failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + Write-Host "git -c user.email=`"dn-bot@microsoft.com`" -c user.name=`"Dotnet Bot`" commit -m `"$PushReason for $Repository/$BranchName`"" + git -c user.email="dn-bot@microsoft.com" -c user.name="Dotnet Bot" commit -m "$PushReason for $Repository/$BranchName" + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Git commit failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + Write-Host 'git push' + git push + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Git push failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + + # Return to the original directory + Pop-Location +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Sdl' -Message $_ + ExitWithExitCode 1 +} \ No newline at end of file diff --git a/eng/common/sdl/run-sdl.ps1 b/eng/common/sdl/run-sdl.ps1 index 9bc25314ae..40a084f796 100644 --- a/eng/common/sdl/run-sdl.ps1 +++ b/eng/common/sdl/run-sdl.ps1 @@ -5,55 +5,65 @@ Param( [string] $GdnFolder, [string[]] $ToolsList, [string] $UpdateBaseline, - [string] $GuardianLoggerLevel="Standard", + [string] $GuardianLoggerLevel='Standard', [string[]] $CrScanAdditionalRunConfigParams, [string[]] $PoliCheckAdditionalRunConfigParams ) -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' Set-StrictMode -Version 2.0 +$disableConfigureToolsetImport = $true $LASTEXITCODE = 0 -# We store config files in the r directory of .gdn -Write-Host $ToolsList -$gdnConfigPath = Join-Path $GdnFolder "r" -$ValidPath = Test-Path $GuardianCliLocation +try { + . $PSScriptRoot\..\tools.ps1 -if ($ValidPath -eq $False) -{ - Write-Host "Invalid Guardian CLI Location." - exit 1 -} + # We store config files in the r directory of .gdn + Write-Host $ToolsList + $gdnConfigPath = Join-Path $GdnFolder 'r' + $ValidPath = Test-Path $GuardianCliLocation -$configParam = @("--config") - -foreach ($tool in $ToolsList) { - $gdnConfigFile = Join-Path $gdnConfigPath "$tool-configure.gdnconfig" - Write-Host $tool - # We have to manually configure tools that run on source to look at the source directory only - if ($tool -eq "credscan") { - Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory < $TargetDirectory `" `" OutputType < pre `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})" - & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory < $TargetDirectory " "OutputType < pre" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams}) - if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE - } - } - if ($tool -eq "policheck") { - Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target < $TargetDirectory `" $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams})" - & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target < $TargetDirectory " $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams}) - if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE - } + if ($ValidPath -eq $False) + { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Invalid Guardian CLI Location." + ExitWithExitCode 1 } - $configParam+=$gdnConfigFile -} + $configParam = @('--config') -Write-Host "$GuardianCliLocation run --working-directory $WorkingDirectory --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel $configParam" -& $GuardianCliLocation run --working-directory $WorkingDirectory --tool $tool --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel $configParam -if ($LASTEXITCODE -ne 0) { - Write-Host "Guardian run for $ToolsList using $configParam failed with exit code $LASTEXITCODE." - exit $LASTEXITCODE + foreach ($tool in $ToolsList) { + $gdnConfigFile = Join-Path $gdnConfigPath "$tool-configure.gdnconfig" + Write-Host $tool + # We have to manually configure tools that run on source to look at the source directory only + if ($tool -eq 'credscan') { + Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory < $TargetDirectory `" `" OutputType < pre `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})" + & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory < $TargetDirectory " "OutputType < pre" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams}) + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Guardian configure for $tool failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + } + if ($tool -eq 'policheck') { + Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target < $TargetDirectory `" $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams})" + & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target < $TargetDirectory " $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams}) + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Guardian configure for $tool failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } + } + + $configParam+=$gdnConfigFile + } + + Write-Host "$GuardianCliLocation run --working-directory $WorkingDirectory --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel $configParam" + & $GuardianCliLocation run --working-directory $WorkingDirectory --tool $tool --baseline mainbaseline --update-baseline $UpdateBaseline --logger-level $GuardianLoggerLevel $configParam + if ($LASTEXITCODE -ne 0) { + Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Guardian run for $ToolsList using $configParam failed with exit code $LASTEXITCODE." + ExitWithExitCode $LASTEXITCODE + } } +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Sdl' -Message $_ + ExitWithExitCode 1 +} \ No newline at end of file diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml index 52e2ff021d..2973bcaf3a 100644 --- a/eng/common/templates/job/execute-sdl.yml +++ b/eng/common/templates/job/execute-sdl.yml @@ -40,13 +40,13 @@ jobs: itemPattern: "**" downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts - -ExtractPath $(Build.SourcesDirectory)\artifacts\BlobArtifacts + -InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts + -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts displayName: Extract Blob Artifacts continueOnError: ${{ parameters.sdlContinueOnError }} - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts - -ExtractPath $(Build.SourcesDirectory)\artifacts\PackageArtifacts + -InputPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts + -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts displayName: Extract Package Artifacts continueOnError: ${{ parameters.sdlContinueOnError }} - task: NuGetToolInstaller@1 diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index ffda80a197..ecebd0f03e 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -1,67 +1,33 @@ +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + parameters: # Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job cancelTimeoutInMinutes: '' - condition: '' - - continueOnError: false - container: '' - + continueOnError: false dependsOn: '' - displayName: '' - - steps: [] - pool: '' - + steps: [] strategy: '' - timeoutInMinutes: '' - variables: [] - workspace: '' - # Job base template specific parameters - # Optional: Enable installing Microbuild plugin - # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix - # _TeamName - the name of your team - # _SignType - 'test' or 'real' +# Job base template specific parameters + # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md + artifacts: '' enableMicrobuild: false - - # Optional: Include PublishBuildArtifacts task enablePublishBuildArtifacts: false - - # Optional: Enable publishing to the build asset registry enablePublishBuildAssets: false - - # Optional: Prevent gather/push manifest from executing when using publishing pipelines - enablePublishUsingPipelines: false - - # Optional: Include PublishTestResults task enablePublishTestResults: false - - # Optional: enable sending telemetry - enableTelemetry: false - - # Optional: define the helix repo for telemetry (example: 'dotnet/arcade') - helixRepo: '' - - # Optional: define the helix type for telemetry (example: 'build/product/') - helixType: '' - - # Required: name of the job + enablePublishUsingPipelines: false name: '' - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + preSteps: [] runAsPublic: false -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - jobs: - job: ${{ parameters.name }} @@ -93,7 +59,7 @@ jobs: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} variables: - - ${{ if eq(parameters.enableTelemetry, 'true') }}: + - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE value: '$(Build.Repository.Uri)' - ${{ each variable in parameters.variables }}: @@ -125,21 +91,12 @@ jobs: workspace: ${{ parameters.workspace }} steps: - - ${{ if eq(parameters.enableTelemetry, 'true') }}: - # Telemetry tasks are built from https://github.com/dotnet/arcade-extensions - - task: sendStartTelemetry@0 - displayName: 'Send Helix Start Telemetry' - inputs: - helixRepo: ${{ parameters.helixRepo }} - ${{ if ne(parameters.helixType, '') }}: - helixType: ${{ parameters.helixType }} - buildConfig: $(_BuildConfig) - runAsPublic: ${{ parameters.runAsPublic }} - continueOnError: ${{ parameters.continueOnError }} - condition: always() + - ${{ if ne(parameters.preSteps, '') }}: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - task: MicroBuildSigningPlugin@2 displayName: Install MicroBuild plugin inputs: @@ -151,9 +108,16 @@ jobs: continueOnError: ${{ parameters.continueOnError }} condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - task: NuGetAuthenticate@0 + - ${{ if or(eq(parameters.artifacts.download, 'true'), ne(parameters.artifacts.download, '')) }}: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: current + artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} + targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} + itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} + - ${{ each step in parameters.steps }}: - ${{ step }} @@ -166,20 +130,60 @@ jobs: env: TeamName: $(_TeamName) - - ${{ if eq(parameters.enableTelemetry, 'true') }}: - # Telemetry tasks are built from https://github.com/dotnet/arcade-extensions - - task: sendEndTelemetry@0 - displayName: 'Send Helix End Telemetry' - continueOnError: ${{ parameters.continueOnError }} - condition: always() + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if or(eq(parameters.artifacts.publish.artifacts, 'true'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - task: PublishBuildArtifacts@1 + displayName: Publish pipeline artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if or(eq(parameters.artifacts.publish.logs, 'true'), ne(parameters.artifacts.publish.logs, '')) }}: + - publish: artifacts/log + artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: Publish logs + continueOnError: true + condition: always() + - ${{ if or(eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - ${{ if and(ne(parameters.enablePublishUsingPipelines, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: CopyFiles@2 + displayName: Gather Asset Manifests + inputs: + SourceFolder: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/AssetManifest' + TargetFolder: '$(Build.ArtifactStagingDirectory)/AssetManifests' + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) - - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - task: PublishBuildArtifacts@1 + displayName: Push Asset Manifests + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/AssetManifests' + PublishLocation: Container + ArtifactName: AssetManifests + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), eq(variables['_DotNetPublishToBlobFeed'], 'true')) + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: - task: PublishBuildArtifacts@1 displayName: Publish Logs inputs: PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' PublishLocation: Container - ArtifactName: $(Agent.Os)_$(Agent.JobName) + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} continueOnError: true condition: always() diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml index 6a2f98c036..c08225a9a9 100644 --- a/eng/common/templates/jobs/jobs.yml +++ b/eng/common/templates/jobs/jobs.yml @@ -1,19 +1,10 @@ parameters: - # Optional: 'true' if failures in job.yml job should not fail the job + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md continueOnError: false - # Optional: Enable installing Microbuild plugin - # if 'true', these "variables" must be specified in the variables object or as part of the queue matrix - # _TeamName - the name of your team - # _SignType - 'test' or 'real' - enableMicrobuild: false - # Optional: Include PublishBuildArtifacts task enablePublishBuildArtifacts: false - # Optional: Enable publishing to the build asset registry - enablePublishBuildAssets: false - # Optional: Enable publishing using release pipelines enablePublishUsingPipelines: false @@ -23,19 +14,9 @@ parameters: # Optional: Include toolset dependencies in the generated graph files includeToolset: false - # Optional: Include PublishTestResults task - enablePublishTestResults: false - - # Optional: enable sending telemetry - # if enabled then the 'helixRepo' parameter should also be specified - enableTelemetry: false - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job jobs: [] - # Optional: define the helix repo for telemetry (example: 'dotnet/arcade') - helixRepo: '' - # Optional: Override automatically derived dependsOn value for "publish build assets" job publishBuildAssetsDependsOn: '' @@ -62,29 +43,30 @@ jobs: name: ${{ job.job }} -- ${{ if and(eq(parameters.enablePublishBuildAssets, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: ../job/publish-build-assets.yml - parameters: - continueOnError: ${{ parameters.continueOnError }} - dependsOn: - - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.publishBuildAssetsDependsOn }}: - - ${{ job.job }} - - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.jobs }}: - - ${{ job.job }} - pool: - vmImage: vs2017-win2016 - runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} - -- ${{ if and(eq(parameters.graphFileGeneration.enabled, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - template: ../job/generate-graph-files.yml - parameters: - continueOnError: ${{ parameters.continueOnError }} - includeToolset: ${{ parameters.graphFileGeneration.includeToolset }} - dependsOn: - - Asset_Registry_Publish - pool: - vmImage: vs2017-win2016 +- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - template: ../job/publish-build-assets.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + pool: + vmImage: vs2017-win2016 + runAsPublic: ${{ parameters.runAsPublic }} + publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + + - ${{ if eq(parameters.graphFileGeneration.enabled, true) }}: + - template: ../job/generate-graph-files.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + includeToolset: ${{ parameters.graphFileGeneration.includeToolset }} + dependsOn: + - Asset_Registry_Publish + pool: + vmImage: vs2017-win2016 diff --git a/eng/common/templates/post-build/channels/generic-internal-channel.yml b/eng/common/templates/post-build/channels/generic-internal-channel.yml index 68fdec0290..700211049b 100644 --- a/eng/common/templates/post-build/channels/generic-internal-channel.yml +++ b/eng/common/templates/post-build/channels/generic-internal-channel.yml @@ -1,4 +1,7 @@ parameters: + artifactsPublishingAdditionalParameters: '' + dependsOn: + - Validate publishInstallersAndChecksums: false symbolPublishingAdditionalParameters: '' stageName: '' @@ -10,14 +13,14 @@ parameters: stages: - stage: ${{ parameters.stageName }} - dependsOn: validate + dependsOn: ${{ parameters.dependsOn }} variables: - template: ../common-variables.yml displayName: ${{ parameters.channelName }} Publishing jobs: - template: ../setup-maestro-vars.yml - - job: + - job: publish_symbols displayName: Symbol Publishing dependsOn: setupMaestroVars condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.channelId }} )) @@ -27,16 +30,27 @@ stages: vmImage: 'windows-2019' steps: - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - artifactName: 'BlobArtifacts' + displayName: Download Build Assets continueOnError: true + inputs: + buildType: 'current' + downloadType: 'specific' + itemPattern: | + PDBArtifacts/** + BlobArtifacts/** + downloadPath: '$(Build.ArtifactStagingDirectory)' - - task: DownloadBuildArtifacts@0 - displayName: Download PDB Artifacts + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@0 + displayName: 'Authenticate to AzDO Feeds' + + - task: PowerShell@2 + displayName: Enable cross-org publishing inputs: - artifactName: 'PDBArtifacts' - continueOnError: true + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) - task: PowerShell@2 displayName: Publish @@ -49,14 +63,18 @@ stages: /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' /p:Configuration=Release + /p:PublishToMSDL=false ${{ parameters.symbolPublishingAdditionalParameters }} + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'SymbolPublishing' + - job: publish_assets displayName: Publish Assets dependsOn: setupMaestroVars variables: - - group: DotNet-Blob-Feed - - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - name: IsStableBuild @@ -66,22 +84,16 @@ stages: vmImage: 'windows-2019' steps: - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts + displayName: Download Build Assets + continueOnError: true inputs: - buildType: current - artifactName: PackageArtifacts - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: current - artifactName: BlobArtifacts - - - task: DownloadBuildArtifacts@0 - displayName: Download Asset Manifests - inputs: - buildType: current - artifactName: AssetManifests + buildType: 'current' + downloadType: 'specific' + itemPattern: | + PackageArtifacts/** + BlobArtifacts/** + AssetManifests/** + downloadPath: '$(Build.ArtifactStagingDirectory)' - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' @@ -120,7 +132,6 @@ stages: /p:ChecksumsAzureAccountKey=$(InternalChecksumsBlobFeedKey) /p:InstallersTargetStaticFeed=$(InternalInstallersBlobFeedUrl) /p:InstallersAzureAccountKey=$(InternalInstallersBlobFeedKey) - /p:PublishToAzureDevOpsNuGetFeeds=true /p:AzureDevOpsStaticShippingFeed='${{ parameters.shippingFeed }}' /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' /p:AzureDevOpsStaticTransportFeed='${{ parameters.transportFeed }}' @@ -130,6 +141,11 @@ stages: /p:PublishToMSDL=false ${{ parameters.artifactsPublishingAdditionalParameters }} + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'AssetsPublishing' + - template: ../../steps/promote-build.yml parameters: ChannelId: ${{ parameters.channelId }} diff --git a/eng/common/templates/post-build/channels/generic-public-channel.yml b/eng/common/templates/post-build/channels/generic-public-channel.yml index c4bc1897d8..fbb5a19b67 100644 --- a/eng/common/templates/post-build/channels/generic-public-channel.yml +++ b/eng/common/templates/post-build/channels/generic-public-channel.yml @@ -1,5 +1,7 @@ parameters: artifactsPublishingAdditionalParameters: '' + dependsOn: + - Validate publishInstallersAndChecksums: false symbolPublishingAdditionalParameters: '' stageName: '' @@ -11,14 +13,14 @@ parameters: stages: - stage: ${{ parameters.stageName }} - dependsOn: validate + dependsOn: ${{ parameters.dependsOn }} variables: - template: ../common-variables.yml displayName: ${{ parameters.channelName }} Publishing jobs: - template: ../setup-maestro-vars.yml - - job: + - job: publish_symbols displayName: Symbol Publishing dependsOn: setupMaestroVars condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], format('[{0}]', ${{ parameters.channelId }} )) @@ -28,16 +30,15 @@ stages: vmImage: 'windows-2019' steps: - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - artifactName: 'BlobArtifacts' + displayName: Download Build Assets continueOnError: true - - - task: DownloadBuildArtifacts@0 - displayName: Download PDB Artifacts inputs: - artifactName: 'PDBArtifacts' - continueOnError: true + buildType: 'current' + downloadType: 'specific' + itemPattern: | + PDBArtifacts/** + BlobArtifacts/** + downloadPath: '$(Build.ArtifactStagingDirectory)' # This is necessary whenever we want to publish/restore to an AzDO private feed # Since sdk-task.ps1 tries to restore packages we need to do this authentication here @@ -64,6 +65,11 @@ stages: /p:Configuration=Release ${{ parameters.symbolPublishingAdditionalParameters }} + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'SymbolPublishing' + - job: publish_assets displayName: Publish Assets dependsOn: setupMaestroVars @@ -77,24 +83,16 @@ stages: vmImage: 'windows-2019' steps: - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: current - artifactName: PackageArtifacts + displayName: Download Build Assets continueOnError: true - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts inputs: - buildType: current - artifactName: BlobArtifacts - continueOnError: true - - - task: DownloadBuildArtifacts@0 - displayName: Download Asset Manifests - inputs: - buildType: current - artifactName: AssetManifests + buildType: 'current' + downloadType: 'specific' + itemPattern: | + PackageArtifacts/** + BlobArtifacts/** + AssetManifests/** + downloadPath: '$(Build.ArtifactStagingDirectory)' - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' @@ -134,7 +132,6 @@ stages: /p:InstallersAzureAccountKey=$(dotnetcli-storage-key) /p:ChecksumsTargetStaticFeed=$(ChecksumsBlobFeedUrl) /p:ChecksumsAzureAccountKey=$(dotnetclichecksums-storage-key) - /p:PublishToAzureDevOpsNuGetFeeds=true /p:AzureDevOpsStaticShippingFeed='${{ parameters.shippingFeed }}' /p:AzureDevOpsStaticShippingFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' /p:AzureDevOpsStaticTransportFeed='${{ parameters.transportFeed }}' @@ -143,6 +140,11 @@ stages: /p:AzureDevOpsStaticSymbolsFeedKey='$(dn-bot-dnceng-artifact-feeds-rw)' ${{ parameters.artifactsPublishingAdditionalParameters }} + - template: ../../steps/publish-logs.yml + parameters: + StageLabel: '${{ parameters.stageName }}' + JobLabel: 'AssetsPublishing' + - template: ../../steps/promote-build.yml parameters: ChannelId: ${{ parameters.channelId }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index 216d043e4e..9505cf170f 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -4,7 +4,7 @@ variables: - group: DotNet-DotNetCli-Storage - group: DotNet-MSRC-Storage - group: Publish-Build-Assets - + # .NET Core 3.1 Dev - name: PublicDevRelease_31_Channel_Id value: 128 @@ -49,6 +49,10 @@ variables: - name: NetCore_31_Blazor_Features_Channel_Id value: 531 + # .NET Core Experimental + - name: NetCore_Experimental_Channel_Id + value: 562 + # Whether the build is internal or not - name: IsInternalBuild value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 9921743bcd..8a8d84f202 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -17,11 +17,14 @@ parameters: signingValidationAdditionalParameters: '' # Which stages should finish execution before post-build stages start - dependsOn: [build] + validateDependsOn: + - build + publishDependsOn: + - Validate stages: -- stage: validate - dependsOn: ${{ parameters.dependsOn }} +- stage: Validate + dependsOn: ${{ parameters.validateDependsOn }} displayName: Validate jobs: - ${{ if eq(parameters.enableNugetValidation, 'true') }}: @@ -46,6 +49,8 @@ stages: - ${{ if eq(parameters.enableSigningValidation, 'true') }}: - job: displayName: Signing Validation + variables: + - template: common-variables.yml pool: vmImage: 'windows-2019' steps: @@ -55,6 +60,18 @@ stages: buildType: current artifactName: PackageArtifacts + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@0 + displayName: 'Authenticate to AzDO Feeds' + + - task: PowerShell@2 + displayName: Enable cross-org publishing + inputs: + filePath: eng\common\enable-cross-org-publishing.ps1 + arguments: -token $(dn-bot-dnceng-artifact-feeds-rw) + - task: PowerShell@2 displayName: Validate inputs: @@ -62,9 +79,13 @@ stages: arguments: -task SigningValidation -restore -msbuildEngine dotnet /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' - /p:Configuration=Release ${{ parameters.signingValidationAdditionalParameters }} + - template: ../steps/publish-logs.yml + parameters: + StageLabel: 'Validation' + JobLabel: 'Signing' + - ${{ if eq(parameters.enableSourceLinkValidation, 'true') }}: - job: displayName: SourceLink Validation @@ -100,6 +121,7 @@ stages: - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} stageName: 'NetCore_Dev5_Publish' @@ -112,18 +134,7 @@ stages: - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Dev31_Publish' - channelName: '.NET Core 3.1 Dev' - channelId: 128 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} stageName: 'Net_Eng_Latest_Publish' @@ -136,6 +147,7 @@ stages: - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} stageName: 'Net_Eng_Validation_Publish' @@ -148,90 +160,7 @@ stages: - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_3_Tools_Validation_Publish' - channelName: '.NET 3 Tools - Validation' - channelId: 390 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_3_Tools_Publish' - channelName: '.NET 3 Tools' - channelId: 344 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Release30_Publish' - channelName: '.NET Core 3.0 Release' - channelId: 19 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Release31_Publish' - channelName: '.NET Core 3.1 Release' - channelId: 129 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_Blazor31_Features_Publish' - channelName: '.NET Core 3.1 Blazor Features' - channelId: 531 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-blazor/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-blazor/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-blazor-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_30_Internal_Servicing_Publishing' - channelName: '.NET Core 3.0 Internal Servicing' - channelId: 184 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NetCore_31_Internal_Servicing_Publishing' - channelName: '.NET Core 3.1 Internal Servicing' - channelId: 550 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} stageName: 'General_Testing_Publish' @@ -244,6 +173,7 @@ stages: - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} stageName: 'NETCore_Tooling_Dev_Publishing' @@ -256,6 +186,7 @@ stages: - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} stageName: 'NETCore_Tooling_Release_Publishing' @@ -265,74 +196,28 @@ stages: shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json' symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools-symbols/nuget/v3/index.json' -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_301xx_Publishing' - channelName: '.NET Core SDK 3.0.1xx' - channelId: 556 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3-symbols/nuget/v3/index.json' - - template: \eng\common\templates\post-build\channels\generic-internal-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_301xx_Internal_Publishing' - channelName: '.NET Core SDK 3.0.1xx Internal' - channelId: 555 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3-internal-symbols/nuget/v3/index.json' + stageName: 'NET_Internal_Tooling_Publishing' + channelName: '.NET Internal Tooling' + channelId: 551 + transportFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal-symbols/nuget/v3/index.json' - template: \eng\common\templates\post-build\channels\generic-public-channel.yml parameters: artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + dependsOn: ${{ parameters.publishDependsOn }} publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_311xx_Publishing' - channelName: '.NET Core SDK 3.1.1xx' - channelId: 560 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_311xx_Internal_Publishing' - channelName: '.NET Core SDK 3.1.1xx Internal' - channelId: 559 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-public-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_312xx_Publishing' - channelName: '.NET Core SDK 3.1.2xx' - channelId: 558 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet3.1-symbols/nuget/v3/index.json' - -- template: \eng\common\templates\post-build\channels\generic-internal-channel.yml - parameters: - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - publishInstallersAndChecksums: ${{ parameters.publishInstallersAndChecksums }} - symbolPublishingAdditionalParameters: ${{ parameters.symbolPublishingAdditionalParameters }} - stageName: 'NETCore_SDK_312xx_Internal_Publishing' - channelName: '.NET Core SDK 3.1.2xx Internal' - channelId: 557 - transportFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v3/index.json' - shippingFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v3/index.json' - symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-symbols/nuget/v3/index.json' \ No newline at end of file + stageName: 'NETCore_Experimental_Publishing' + channelName: '.NET Core Experimental' + channelId: 562 + transportFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json' + shippingFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json' + symbolsFeed: 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental-symbols/nuget/v3/index.json' diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml index 56242b068e..716b53f740 100644 --- a/eng/common/templates/post-build/setup-maestro-vars.yml +++ b/eng/common/templates/post-build/setup-maestro-vars.yml @@ -4,6 +4,8 @@ jobs: pool: vmImage: 'windows-2019' steps: + - checkout: none + - task: DownloadBuildArtifacts@0 displayName: Download Release Configs inputs: @@ -14,5 +16,25 @@ jobs: name: setReleaseVars displayName: Set Release Configs Vars inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/setup-maestro-vars.ps1 - arguments: -ReleaseConfigsPath '$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt' + targetType: inline + script: | + try { + $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt + + $BarId = $Content | Select -Index 0 + + $Channels = "" + $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," } + + $IsStableBuild = $Content | Select -Index 2 + + Write-Host "##vso[task.setvariable variable=BARBuildId;isOutput=true]$BarId" + Write-Host "##vso[task.setvariable variable=InitialChannels;isOutput=true]$Channels" + Write-Host "##vso[task.setvariable variable=IsStableBuild;isOutput=true]$IsStableBuild" + } + catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + exit 1 + } diff --git a/eng/common/templates/steps/publish-logs.yml b/eng/common/templates/steps/publish-logs.yml new file mode 100644 index 0000000000..f91751fe78 --- /dev/null +++ b/eng/common/templates/steps/publish-logs.yml @@ -0,0 +1,23 @@ +parameters: + StageLabel: '' + JobLabel: '' + +steps: +- task: Powershell@2 + displayName: Prepare Binlogs to Upload + inputs: + targetType: inline + script: | + New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + continueOnError: true + condition: always() + +- task: PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' + PublishLocation: Container + ArtifactName: PostBuildLogs + continueOnError: true + condition: always() diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml index 05df886f55..30becf01ea 100644 --- a/eng/common/templates/steps/send-to-helix.yml +++ b/eng/common/templates/steps/send-to-helix.yml @@ -23,6 +23,7 @@ parameters: EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting int) Creator: '' # optional -- if the build is external, use this to specify who is sending the job DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() @@ -55,6 +56,7 @@ steps: DotNetCliVersion: ${{ parameters.DotNetCliVersion }} EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} Creator: ${{ parameters.Creator }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) @@ -85,6 +87,7 @@ steps: DotNetCliVersion: ${{ parameters.DotNetCliVersion }} EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} Creator: ${{ parameters.Creator }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 617db167ce..d3a432878e 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -5,7 +5,7 @@ [bool]$ci = if (Test-Path variable:ci) { $ci } else { $false } # Build configuration. Common values include 'Debug' and 'Release', but the repository may use other names. -[string]$configuration = if (Test-Path variable:configuration) { $configuration } else { "Debug" } +[string]$configuration = if (Test-Path variable:configuration) { $configuration } else { 'Debug' } # Set to true to output binary log from msbuild. Note that emitting binary log slows down the build. # Binary log must be enabled on CI. @@ -24,7 +24,7 @@ [bool]$restore = if (Test-Path variable:restore) { $restore } else { $true } # Adjusts msbuild verbosity level. -[string]$verbosity = if (Test-Path variable:verbosity) { $verbosity } else { "minimal" } +[string]$verbosity = if (Test-Path variable:verbosity) { $verbosity } else { 'minimal' } # Set to true to reuse msbuild nodes. Recommended to not reuse on CI. [bool]$nodeReuse = if (Test-Path variable:nodeReuse) { $nodeReuse } else { !$ci } @@ -41,21 +41,23 @@ # Enable repos to use a particular version of the on-line dotnet-install scripts. # default URL: https://dot.net/v1/dotnet-install.ps1 -[string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { "v1" } +[string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { 'v1' } # True to use global NuGet cache instead of restoring packages to repository-local directory. [bool]$useGlobalNuGetCache = if (Test-Path variable:useGlobalNuGetCache) { $useGlobalNuGetCache } else { !$ci } # An array of names of processes to stop on script exit if prepareMachine is true. -$processesToStopOnExit = if (Test-Path variable:processesToStopOnExit) { $processesToStopOnExit } else { @("msbuild", "dotnet", "vbcscompiler") } +$processesToStopOnExit = if (Test-Path variable:processesToStopOnExit) { $processesToStopOnExit } else { @('msbuild', 'dotnet', 'vbcscompiler') } + +$disableConfigureToolsetImport = if (Test-Path variable:disableConfigureToolsetImport) { $disableConfigureToolsetImport } else { $null } set-strictmode -version 2.0 -$ErrorActionPreference = "Stop" +$ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 function Create-Directory([string[]] $path) { if (!(Test-Path $path)) { - New-Item -path $path -force -itemType "Directory" | Out-Null + New-Item -path $path -force -itemType 'Directory' | Out-Null } } @@ -96,7 +98,10 @@ function Exec-Process([string]$command, [string]$commandArgs) { } } -function InitializeDotNetCli([bool]$install) { +# createSdkLocationFile parameter enables a file being generated under the toolset directory +# which writes the sdk's location into. This is only necessary for cmd --> powershell invocations +# as dot sourcing isn't possible. +function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) { if (Test-Path variable:global:_DotNetInstallDir) { return $global:_DotNetInstallDir } @@ -119,7 +124,7 @@ function InitializeDotNetCli([bool]$install) { # Find the first path on %PATH% that contains the dotnet.exe if ($useInstalledDotNetCli -and (-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -eq $null)) { - $dotnetCmd = Get-Command "dotnet.exe" -ErrorAction SilentlyContinue + $dotnetCmd = Get-Command 'dotnet.exe' -ErrorAction SilentlyContinue if ($dotnetCmd -ne $null) { $env:DOTNET_INSTALL_DIR = Split-Path $dotnetCmd.Path -Parent } @@ -132,13 +137,13 @@ function InitializeDotNetCli([bool]$install) { if ((-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -ne $null) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$dotnetSdkVersion"))) { $dotnetRoot = $env:DOTNET_INSTALL_DIR } else { - $dotnetRoot = Join-Path $RepoRoot ".dotnet" + $dotnetRoot = Join-Path $RepoRoot '.dotnet' if (-not (Test-Path(Join-Path $dotnetRoot "sdk\$dotnetSdkVersion"))) { if ($install) { InstallDotNetSdk $dotnetRoot $dotnetSdkVersion } else { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Unable to find dotnet with SDK version '$dotnetSdkVersion'" + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unable to find dotnet with SDK version '$dotnetSdkVersion'" ExitWithExitCode 1 } } @@ -146,6 +151,24 @@ function InitializeDotNetCli([bool]$install) { $env:DOTNET_INSTALL_DIR = $dotnetRoot } + # Creates a temporary file under the toolset dir. + # The following code block is protecting against concurrent access so that this function can + # be called in parallel. + if ($createSdkLocationFile) { + do { + $sdkCacheFileTemp = Join-Path $ToolsetDir $([System.IO.Path]::GetRandomFileName()) + } + until (!(Test-Path $sdkCacheFileTemp)) + Set-Content -Path $sdkCacheFileTemp -Value $dotnetRoot + + try { + Rename-Item -Force -Path $sdkCacheFileTemp 'sdk.txt' + } catch { + # Somebody beat us + Remove-Item -Path $sdkCacheFileTemp + } + } + # Add dotnet to PATH. This prevents any bare invocation of dotnet in custom # build steps from using anything other than what we've downloaded. # It also ensures that VS msbuild will use the downloaded sdk targets. @@ -154,15 +177,6 @@ function InitializeDotNetCli([bool]$install) { # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build Write-PipelinePrependPath -Path $dotnetRoot - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 - if ($ci) { - $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20 - $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20 - Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20' - Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20' - } - Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0' Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1' @@ -170,7 +184,7 @@ function InitializeDotNetCli([bool]$install) { } function GetDotNetInstallScript([string] $dotnetRoot) { - $installScript = Join-Path $dotnetRoot "dotnet-install.ps1" + $installScript = Join-Path $dotnetRoot 'dotnet-install.ps1' if (!(Test-Path $installScript)) { Create-Directory $dotnetRoot $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit @@ -180,11 +194,18 @@ function GetDotNetInstallScript([string] $dotnetRoot) { return $installScript } -function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $architecture = "") { +function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $architecture = '') { InstallDotNet $dotnetRoot $version $architecture } -function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) { +function InstallDotNet([string] $dotnetRoot, + [string] $version, + [string] $architecture = '', + [string] $runtime = '', + [bool] $skipNonVersionedFiles = $false, + [string] $runtimeSourceFeed = '', + [string] $runtimeSourceFeedKey = '') { + $installScript = GetDotNetInstallScript $dotnetRoot $installParameters = @{ Version = $version @@ -195,10 +216,32 @@ function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $archit if ($runtime) { $installParameters.Runtime = $runtime } if ($skipNonVersionedFiles) { $installParameters.SkipNonVersionedFiles = $skipNonVersionedFiles } - & $installScript @installParameters - if ($lastExitCode -ne 0) { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Failed to install dotnet cli (exit code '$lastExitCode')." - ExitWithExitCode $lastExitCode + try { + & $installScript @installParameters + } + catch { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet runtime '$runtime' from public location." + + # Only the runtime can be installed from a custom [private] location. + if ($runtime -and ($runtimeSourceFeed -or $runtimeSourceFeedKey)) { + if ($runtimeSourceFeed) { $installParameters.AzureFeed = $runtimeSourceFeed } + + if ($runtimeSourceFeedKey) { + $decodedBytes = [System.Convert]::FromBase64String($runtimeSourceFeedKey) + $decodedString = [System.Text.Encoding]::UTF8.GetString($decodedBytes) + $installParameters.FeedCredential = $decodedString + } + + try { + & $installScript @installParameters + } + catch { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet runtime '$runtime' from custom location '$runtimeSourceFeed'." + ExitWithExitCode 1 + } + } else { + ExitWithExitCode 1 + } } } @@ -219,12 +262,12 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = } if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs } - $vsMinVersionStr = if ($vsRequirements.version) { $vsRequirements.version } else { "15.9" } + $vsMinVersionStr = if ($vsRequirements.version) { $vsRequirements.version } else { '15.9' } $vsMinVersion = [Version]::new($vsMinVersionStr) # Try msbuild command available in the environment. if ($env:VSINSTALLDIR -ne $null) { - $msbuildCmd = Get-Command "msbuild.exe" -ErrorAction SilentlyContinue + $msbuildCmd = Get-Command 'msbuild.exe' -ErrorAction SilentlyContinue if ($msbuildCmd -ne $null) { # Workaround for https://github.com/dotnet/roslyn/issues/35793 # Due to this issue $msbuildCmd.Version returns 0.0.0.0 for msbuild.exe 16.2+ @@ -248,17 +291,20 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = InitializeVisualStudioEnvironmentVariables $vsInstallDir $vsMajorVersion } else { - if (Get-Member -InputObject $GlobalJson.tools -Name "xcopy-msbuild") { + if (Get-Member -InputObject $GlobalJson.tools -Name 'xcopy-msbuild') { $xcopyMSBuildVersion = $GlobalJson.tools.'xcopy-msbuild' $vsMajorVersion = $xcopyMSBuildVersion.Split('.')[0] } else { $vsMajorVersion = $vsMinVersion.Major $xcopyMSBuildVersion = "$vsMajorVersion.$($vsMinVersion.Minor).0-alpha" } - - $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install + + $vsInstallDir = $null + if ($xcopyMSBuildVersion.Trim() -ine "none") { + $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install + } if ($vsInstallDir -eq $null) { - throw "Unable to find Visual Studio that has required version and components installed" + throw 'Unable to find Visual Studio that has required version and components installed' } } @@ -282,7 +328,7 @@ function InstallXCopyMSBuild([string]$packageVersion) { } function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { - $packageName = "RoslynTools.MSBuild" + $packageName = 'RoslynTools.MSBuild' $packageDir = Join-Path $ToolsDir "msbuild\$packageVersion" $packagePath = Join-Path $packageDir "$packageName.$packageVersion.nupkg" @@ -298,7 +344,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { Unzip $packagePath $packageDir } - return Join-Path $packageDir "tools" + return Join-Path $packageDir 'tools' } # @@ -315,32 +361,32 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { # or $null if no instance meeting the requirements is found on the machine. # function LocateVisualStudio([object]$vsRequirements = $null){ - if (Get-Member -InputObject $GlobalJson.tools -Name "vswhere") { + if (Get-Member -InputObject $GlobalJson.tools -Name 'vswhere') { $vswhereVersion = $GlobalJson.tools.vswhere } else { - $vswhereVersion = "2.5.2" + $vswhereVersion = '2.5.2' } $vsWhereDir = Join-Path $ToolsDir "vswhere\$vswhereVersion" - $vsWhereExe = Join-Path $vsWhereDir "vswhere.exe" + $vsWhereExe = Join-Path $vsWhereDir 'vswhere.exe' if (!(Test-Path $vsWhereExe)) { Create-Directory $vsWhereDir - Write-Host "Downloading vswhere" + Write-Host 'Downloading vswhere' Invoke-WebRequest "https://github.com/Microsoft/vswhere/releases/download/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe } if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs } - $args = @("-latest", "-prerelease", "-format", "json", "-requires", "Microsoft.Component.MSBuild", "-products", "*") + $args = @('-latest', '-prerelease', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*') - if (Get-Member -InputObject $vsRequirements -Name "version") { - $args += "-version" + if (Get-Member -InputObject $vsRequirements -Name 'version') { + $args += '-version' $args += $vsRequirements.version } - if (Get-Member -InputObject $vsRequirements -Name "components") { + if (Get-Member -InputObject $vsRequirements -Name 'components') { foreach ($component in $vsRequirements.components) { - $args += "-requires" + $args += '-requires' $args += $component } } @@ -366,27 +412,27 @@ function InitializeBuildTool() { # Initialize dotnet cli if listed in 'tools' $dotnetRoot = $null - if (Get-Member -InputObject $GlobalJson.tools -Name "dotnet") { + if (Get-Member -InputObject $GlobalJson.tools -Name 'dotnet') { $dotnetRoot = InitializeDotNetCli -install:$restore } - if ($msbuildEngine -eq "dotnet") { + if ($msbuildEngine -eq 'dotnet') { if (!$dotnetRoot) { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "/global.json must specify 'tools.dotnet'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "/global.json must specify 'tools.dotnet'." ExitWithExitCode 1 } - $buildTool = @{ Path = Join-Path $dotnetRoot "dotnet.exe"; Command = "msbuild"; Tool = "dotnet"; Framework = "netcoreapp2.1" } + $buildTool = @{ Path = Join-Path $dotnetRoot 'dotnet.exe'; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'netcoreapp2.1' } } elseif ($msbuildEngine -eq "vs") { try { $msbuildPath = InitializeVisualStudioMSBuild -install:$restore } catch { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message $_ + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ ExitWithExitCode 1 } $buildTool = @{ Path = $msbuildPath; Command = ""; Tool = "vs"; Framework = "net472" } } else { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Unexpected value of -msbuildEngine: '$msbuildEngine'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Unexpected value of -msbuildEngine: '$msbuildEngine'." ExitWithExitCode 1 } @@ -395,15 +441,15 @@ function InitializeBuildTool() { function GetDefaultMSBuildEngine() { # Presence of tools.vs indicates the repo needs to build using VS msbuild on Windows. - if (Get-Member -InputObject $GlobalJson.tools -Name "vs") { - return "vs" + if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { + return 'vs' } - if (Get-Member -InputObject $GlobalJson.tools -Name "dotnet") { - return "dotnet" + if (Get-Member -InputObject $GlobalJson.tools -Name 'dotnet') { + return 'dotnet' } - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "-msbuildEngine must be specified, or /global.json must specify 'tools.dotnet' or 'tools.vs'." ExitWithExitCode 1 } @@ -412,9 +458,9 @@ function GetNuGetPackageCachePath() { # Use local cache on CI to ensure deterministic build, # use global cache in dev builds to avoid cost of downloading packages. if ($useGlobalNuGetCache) { - $env:NUGET_PACKAGES = Join-Path $env:UserProfile ".nuget\packages" + $env:NUGET_PACKAGES = Join-Path $env:UserProfile '.nuget\packages' } else { - $env:NUGET_PACKAGES = Join-Path $RepoRoot ".packages" + $env:NUGET_PACKAGES = Join-Path $RepoRoot '.packages' } } @@ -427,7 +473,7 @@ function GetSdkTaskProject([string]$taskName) { } function InitializeNativeTools() { - if (Get-Member -InputObject $GlobalJson -Name "native-tools") { + if (-Not (Test-Path variable:DisableNativeToolsetInstalls) -And (Get-Member -InputObject $GlobalJson -Name "native-tools")) { $nativeArgs= @{} if ($ci) { $nativeArgs = @{ @@ -456,14 +502,14 @@ function InitializeToolset() { } if (-not $restore) { - Write-PipelineTelemetryError -Category "InitializeToolset" -Message "Toolset version $toolsetVersion has not been restored." + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Toolset version $toolsetVersion has not been restored." ExitWithExitCode 1 } $buildTool = InitializeBuildTool - $proj = Join-Path $ToolsetDir "restore.proj" - $bl = if ($binaryLog) { "/bl:" + (Join-Path $LogDir "ToolsetRestore.binlog") } else { "" } + $proj = Join-Path $ToolsetDir 'restore.proj' + $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'ToolsetRestore.binlog') } else { '' } '' | Set-Content $proj @@ -485,7 +531,7 @@ function ExitWithExitCode([int] $exitCode) { } function Stop-Processes() { - Write-Host "Killing running build processes..." + Write-Host 'Killing running build processes...' foreach ($processName in $processesToStopOnExit) { Get-Process -Name $processName -ErrorAction SilentlyContinue | Stop-Process } @@ -502,13 +548,18 @@ function MSBuild() { # Work around issues with Azure Artifacts credential provider # https://github.com/dotnet/arcade/issues/3932 - if ($ci -and $buildTool.Tool -eq "dotnet") { + if ($ci -and $buildTool.Tool -eq 'dotnet') { dotnet nuget locals http-cache -c + + $env:NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS = 20 + $env:NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS = 20 + Write-PipelineSetVariable -Name 'NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS' -Value '20' + Write-PipelineSetVariable -Name 'NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS' -Value '20' } $toolsetBuildProject = InitializeToolset $path = Split-Path -parent $toolsetBuildProject - $path = Join-Path $path (Join-Path $buildTool.Framework "Microsoft.DotNet.Arcade.Sdk.dll") + $path = Join-Path $path (Join-Path $buildTool.Framework 'Microsoft.DotNet.Arcade.Sdk.dll') $args += "/logger:$path" } @@ -523,12 +574,12 @@ function MSBuild() { function MSBuild-Core() { if ($ci) { if (!$binaryLog) { - Write-PipelineTaskError -Message "Binary log must be enabled in CI build." + Write-PipelineTelemetryError -Category 'Build' -Message 'Binary log must be enabled in CI build.' ExitWithExitCode 1 } if ($nodeReuse) { - Write-PipelineTaskError -Message "Node reuse must be disabled in CI build." + Write-PipelineTelemetryError -Category 'Build' -Message 'Node reuse must be disabled in CI build.' ExitWithExitCode 1 } } @@ -538,10 +589,10 @@ function MSBuild-Core() { $cmdArgs = "$($buildTool.Command) /m /nologo /clp:Summary /v:$verbosity /nr:$nodeReuse /p:ContinuousIntegrationBuild=$ci" if ($warnAsError) { - $cmdArgs += " /warnaserror /p:TreatWarningsAsErrors=true" + $cmdArgs += ' /warnaserror /p:TreatWarningsAsErrors=true' } else { - $cmdArgs += " /p:TreatWarningsAsErrors=false" + $cmdArgs += ' /p:TreatWarningsAsErrors=false' } foreach ($arg in $args) { @@ -553,7 +604,7 @@ function MSBuild-Core() { $exitCode = Exec-Process $buildTool.Path $cmdArgs if ($exitCode -ne 0) { - Write-PipelineTaskError -Message "Build failed." + Write-PipelineTelemetryError Category 'Build' -Message 'Build failed.' $buildLog = GetMSBuildBinaryLogCommandLineArgument $args if ($buildLog -ne $null) { @@ -568,12 +619,12 @@ function GetMSBuildBinaryLogCommandLineArgument($arguments) { foreach ($argument in $arguments) { if ($argument -ne $null) { $arg = $argument.Trim() - if ($arg.StartsWith("/bl:", "OrdinalIgnoreCase")) { - return $arg.Substring("/bl:".Length) + if ($arg.StartsWith('/bl:', "OrdinalIgnoreCase")) { + return $arg.Substring('/bl:'.Length) } - if ($arg.StartsWith("/binaryLogger:", "OrdinalIgnoreCase")) { - return $arg.Substring("/binaryLogger:".Length) + if ($arg.StartsWith('/binaryLogger:', 'OrdinalIgnoreCase')) { + return $arg.Substring('/binaryLogger:'.Length) } } } @@ -583,14 +634,14 @@ function GetMSBuildBinaryLogCommandLineArgument($arguments) { . $PSScriptRoot\pipeline-logging-functions.ps1 -$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..") -$EngRoot = Resolve-Path (Join-Path $PSScriptRoot "..") -$ArtifactsDir = Join-Path $RepoRoot "artifacts" -$ToolsetDir = Join-Path $ArtifactsDir "toolset" -$ToolsDir = Join-Path $RepoRoot ".tools" -$LogDir = Join-Path (Join-Path $ArtifactsDir "log") $configuration -$TempDir = Join-Path (Join-Path $ArtifactsDir "tmp") $configuration -$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot "global.json") | ConvertFrom-Json +$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot '..\..') +$EngRoot = Resolve-Path (Join-Path $PSScriptRoot '..') +$ArtifactsDir = Join-Path $RepoRoot 'artifacts' +$ToolsetDir = Join-Path $ArtifactsDir 'toolset' +$ToolsDir = Join-Path $RepoRoot '.tools' +$LogDir = Join-Path (Join-Path $ArtifactsDir 'log') $configuration +$TempDir = Join-Path (Join-Path $ArtifactsDir 'tmp') $configuration +$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json # true if global.json contains a "runtimes" section $globalJsonHasRuntimes = if ($GlobalJson.tools.PSObject.Properties.Name -Match 'runtimes') { $true } else { $false } @@ -603,3 +654,18 @@ Write-PipelineSetVariable -Name 'Artifacts.Toolset' -Value $ToolsetDir Write-PipelineSetVariable -Name 'Artifacts.Log' -Value $LogDir Write-PipelineSetVariable -Name 'TEMP' -Value $TempDir Write-PipelineSetVariable -Name 'TMP' -Value $TempDir + +# Import custom tools configuration, if present in the repo. +# Note: Import in global scope so that the script set top-level variables without qualification. +if (!$disableConfigureToolsetImport) { + $configureToolsetScript = Join-Path $EngRoot 'configure-toolset.ps1' + if (Test-Path $configureToolsetScript) { + . $configureToolsetScript + if ((Test-Path variable:failOnConfigureToolsetError) -And $failOnConfigureToolsetError) { + if ((Test-Path variable:LastExitCode) -And ($LastExitCode -ne 0)) { + Write-PipelineTelemetryError -Category 'Build' -Message 'configure-toolset.ps1 returned a non-zero exit code' + ExitWithExitCode $LastExitCode + } + } + } +} diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 757d5b9ea4..e071af4ee4 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -81,7 +81,7 @@ function ReadGlobalVersion { local pattern="\"$key\" *: *\"(.*)\"" if [[ ! $line =~ $pattern ]]; then - Write-PipelineTelemetryError -category 'InitializeToolset' "Error: Cannot find \"$key\" in $global_json_file" + Write-PipelineTelemetryError -category 'Build' "Error: Cannot find \"$key\" in $global_json_file" ExitWithExitCode 1 fi @@ -152,15 +152,6 @@ function InitializeDotNetCli { # build steps from using anything other than what we've downloaded. Write-PipelinePrependPath -path "$dotnet_root" - # Work around issues with Azure Artifacts credential provider - # https://github.com/dotnet/arcade/issues/3932 - if [[ "$ci" == true ]]; then - export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20 - export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20 - Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20" - Write-PipelineSetVariable -name "NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS" -value "20" - fi - Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0" Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1" @@ -200,8 +191,30 @@ function InstallDotNet { fi bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg || { local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK (exit code '$exit_code')." - ExitWithExitCode $exit_code + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from public location (exit code '$exit_code')." + + if [[ -n "$runtimeArg" ]]; then + local runtimeSourceFeed='' + if [[ -n "${6:-}" ]]; then + runtimeSourceFeed="--azure-feed $6" + fi + + local runtimeSourceFeedKey='' + if [[ -n "${7:-}" ]]; then + decodedFeedKey=`echo $7 | base64 --decode` + runtimeSourceFeedKey="--feed-credential $decodedFeedKey" + fi + + if [[ -n "$runtimeSourceFeed" || -n "$runtimeSourceFeedKey" ]]; then + bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg $runtimeSourceFeed $runtimeSourceFeedKey || { + local exit_code=$? + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from custom location '$runtimeSourceFeed' (exit code '$exit_code')." + ExitWithExitCode $exit_code + } + else + ExitWithExitCode $exit_code + fi + fi } } @@ -261,6 +274,9 @@ function GetNuGetPackageCachePath { } function InitializeNativeTools() { + if [[ -n "${DisableNativeToolsetInstalls:-}" ]]; then + return + fi if grep -Fq "native-tools" $global_json_file then local nativeArgs="" @@ -310,7 +326,7 @@ function InitializeToolset { local toolset_build_proj=`cat "$toolset_location_file"` if [[ ! -a "$toolset_build_proj" ]]; then - Write-PipelineTelemetryError -category 'InitializeToolset' "Invalid toolset path: $toolset_build_proj" + Write-PipelineTelemetryError -category 'Build' "Invalid toolset path: $toolset_build_proj" ExitWithExitCode 3 fi @@ -341,7 +357,12 @@ function MSBuild { # Work around issues with Azure Artifacts credential provider # https://github.com/dotnet/arcade/issues/3932 if [[ "$ci" == true ]]; then - dotnet nuget locals http-cache -c + "$_InitializeBuildTool" nuget locals http-cache -c + + export NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS=20 + export NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS=20 + Write-PipelineSetVariable -name "NUGET_PLUGIN_HANDSHAKE_TIMEOUT_IN_SECONDS" -value "20" + Write-PipelineSetVariable -name "NUGET_PLUGIN_REQUEST_TIMEOUT_IN_SECONDS" -value "20" fi local toolset_dir="${_InitializeToolset%/*}" @@ -355,12 +376,12 @@ function MSBuild { function MSBuild-Core { if [[ "$ci" == true ]]; then if [[ "$binary_log" != true ]]; then - Write-PipelineTaskError "Binary log must be enabled in CI build." + Write-PipelineTelemetryError -category 'Build' "Binary log must be enabled in CI build." ExitWithExitCode 1 fi if [[ "$node_reuse" == true ]]; then - Write-PipelineTaskError "Node reuse must be disabled in CI build." + Write-PipelineTelemetryError -category 'Build' "Node reuse must be disabled in CI build." ExitWithExitCode 1 fi fi @@ -374,7 +395,7 @@ function MSBuild-Core { "$_InitializeBuildTool" "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" || { local exit_code=$? - Write-PipelineTaskError "Build failed (exit code '$exit_code')." + Write-PipelineTelemetryError -category 'Build' "Build failed (exit code '$exit_code')." ExitWithExitCode $exit_code } } @@ -415,3 +436,18 @@ Write-PipelineSetVariable -name "Artifacts.Toolset" -value "$toolset_dir" Write-PipelineSetVariable -name "Artifacts.Log" -value "$log_dir" Write-PipelineSetVariable -name "Temp" -value "$temp_dir" Write-PipelineSetVariable -name "TMP" -value "$temp_dir" + +# Import custom tools configuration, if present in the repo. +if [ -z "${disable_configure_toolset_import:-}" ]; then + configure_toolset_script="$eng_root/configure-toolset.sh" + if [[ -a "$configure_toolset_script" ]]; then + . "$configure_toolset_script" + fi +fi + +# TODO: https://github.com/dotnet/arcade/issues/1468 +# Temporary workaround to avoid breaking change. +# Remove once repos are updated. +if [[ -n "${useInstalledDotNetCli:-}" ]]; then + use_installed_dotnet_cli="$useInstalledDotNetCli" +fi diff --git a/eng/helix/content/InstallNode.ps1 b/eng/helix/content/InstallNode.ps1 index 862e612582..84425f271b 100644 --- a/eng/helix/content/InstallNode.ps1 +++ b/eng/helix/content/InstallNode.ps1 @@ -48,9 +48,10 @@ Write-Host "Extracting to $tempDir" if (Get-Command -Name 'Microsoft.PowerShell.Archive\Expand-Archive' -ErrorAction Ignore) { # Use built-in commands where possible as they are cross-plat compatible - Microsoft.PowerShell.Archive\Expand-Archive -Path "nodejs.zip" -DestinationPath $tempDir + Microsoft.PowerShell.Archive\Expand-Archive -Path "nodejs.zip" -DestinationPath $tempDir -Force } else { + Remove-Item $tempDir -Recurse -ErrorAction Ignore # Fallback to old approach for old installations of PowerShell Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory("nodejs.zip", $tempDir) diff --git a/eng/helix/helix.proj b/eng/helix/helix.proj index 105134743c..f5b74b845c 100644 --- a/eng/helix/helix.proj +++ b/eng/helix/helix.proj @@ -16,7 +16,7 @@ - pr/aspnet/aspnetcore + pr/dotnet/aspnetcore private-$(USERNAME) private-$(USER) true diff --git a/eng/scripts/CodeCheck.ps1 b/eng/scripts/CodeCheck.ps1 index 007abebc8c..474d8e2e81 100644 --- a/eng/scripts/CodeCheck.ps1 +++ b/eng/scripts/CodeCheck.ps1 @@ -120,7 +120,7 @@ try { foreach ($unexpectedVar in $versionVars) { LogError ` - "Version variable '$unexpectedVar' does not have a matching entry in Version.Details.xml. See https://github.com/aspnet/AspNetCore/blob/master/docs/ReferenceResolution.md for instructions on how to add a new dependency." ` + "Version variable '$unexpectedVar' does not have a matching entry in Version.Details.xml. See https://github.com/dotnet/aspnetcore/blob/master/docs/ReferenceResolution.md for instructions on how to add a new dependency." ` -filepath "$repoRoot\eng\Versions.props" } @@ -129,7 +129,8 @@ try { Get-ChildItem "$repoRoot/*.sln" -Recurse ` | ? { # These .sln files are used by the templating engine. - ($_.Name -ne "BlazorServerWeb_CSharp.sln") + ($_.Name -ne "BlazorServerWeb_CSharp.sln") -and + ($_.Name -ne "BlazorWasm-CSharp.sln") } ` | % { Write-Host " Checking $(Split-Path -Leaf $_)" @@ -161,16 +162,15 @@ try { & $PSScriptRoot\GenerateReferenceAssemblies.ps1 -ci:$ci } - # Temporarily disable package baseline generation while we stage for publishing - # Write-Host "Re-generating package baselines" - # Invoke-Block { - # & dotnet run -p "$repoRoot/eng/tools/BaselineGenerator/" - # } + Write-Host "Re-generating package baselines" + Invoke-Block { + & dotnet run -p "$repoRoot/eng/tools/BaselineGenerator/" + } Write-Host "Run git diff to check for pending changes" # Redirect stderr to stdout because PowerShell does not consistently handle output to stderr - $changedFiles = & cmd /c 'git --no-pager diff --ignore-space-at-eol --name-only 2>nul' + $changedFiles = & cmd /c 'git --no-pager diff --ignore-space-change --name-only 2>nul' # Temporary: Disable check for blazor js file $changedFilesExclusion = "src/Components/Web.JS/dist/Release/blazor.server.js" @@ -178,10 +178,9 @@ try { if ($changedFiles) { foreach ($file in $changedFiles) { if ($file -eq $changedFilesExclusion) {continue} - $filePath = Resolve-Path "${repoRoot}/${file}" LogError "Generated code is not up to date in $file. You might need to regenerate the reference assemblies or project list (see docs/ReferenceAssemblies.md and docs/ReferenceResolution.md)" -filepath $filePath - & git --no-pager diff --ignore-space-at-eol $filePath + & git --no-pager diff --ignore-space-change $filePath } } } diff --git a/eng/scripts/InstallVisualStudio.ps1 b/eng/scripts/InstallVisualStudio.ps1 index bbccdaacad..844da67bba 100644 --- a/eng/scripts/InstallVisualStudio.ps1 +++ b/eng/scripts/InstallVisualStudio.ps1 @@ -23,7 +23,7 @@ Run the installer without UI and wait for installation to complete. .LINK https://visualstudio.com - https://github.com/aspnet/AspNetCore/blob/master/docs/BuildFromSource.md + https://github.com/dotnet/aspnetcore/blob/master/docs/BuildFromSource.md .EXAMPLE To install VS 2019 Enterprise, run this command in PowerShell: diff --git a/eng/scripts/ci-source-build.sh b/eng/scripts/ci-source-build.sh index 3387125d78..dd737ac473 100755 --- a/eng/scripts/ci-source-build.sh +++ b/eng/scripts/ci-source-build.sh @@ -9,10 +9,10 @@ set -euo pipefail scriptroot="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" reporoot="$(dirname "$(dirname "$scriptroot")")" - # Build repo tasks +# Build repo tasks "$reporoot/eng/common/build.sh" --restore --build --ci --configuration Release /p:ProjectToBuild=$reporoot/eng/tools/RepoTasks/RepoTasks.csproj export DotNetBuildFromSource='true' - # Build projects +# Build projects "$reporoot/eng/common/build.sh" --restore --build --pack "$@" diff --git a/eng/targets/Helix.Common.props b/eng/targets/Helix.Common.props index 8ea26294a2..419c117b6b 100644 --- a/eng/targets/Helix.Common.props +++ b/eng/targets/Helix.Common.props @@ -1,10 +1,4 @@ - - - true - - - @@ -12,15 +6,15 @@ - - - - - - - + + + + + + + @@ -28,20 +22,27 @@ - + - + + + + + + + + - + - + @@ -53,4 +54,5 @@ + diff --git a/eng/targets/Helix.targets b/eng/targets/Helix.targets index d3a45dfa45..16f5e9f5a2 100644 --- a/eng/targets/Helix.targets +++ b/eng/targets/Helix.targets @@ -42,7 +42,7 @@ Usage: dotnet msbuild /t:Helix src/MyTestProject.csproj - <_HelixProjectTargetQueue Include="%(HelixAvailableTargetQueue.Identity)" Condition="'%(HelixAvailableTargetQueue.Identity)' != '' AND '$(_SelectedPlatforms.Contains(%(Platform)))' == 'true' AND '%(EnableByDefault)' == 'true'" /> + <_HelixProjectTargetQueue Include="%(HelixAvailableTargetQueue.Identity)" Condition="'%(HelixAvailableTargetQueue.Identity)' != '' AND '$(_SelectedPlatforms.Contains(%(Platform)))' == 'true'" /> <_HelixApplicableTargetQueue Include="%(_HelixProjectTargetQueue.Identity)" Condition="'%(Identity)' == '$(HelixTargetQueue)'" /> diff --git a/eng/targets/Npm.Common.targets b/eng/targets/Npm.Common.targets index 062a9d3a8f..7695ed7039 100644 --- a/eng/targets/Npm.Common.targets +++ b/eng/targets/Npm.Common.targets @@ -20,16 +20,20 @@ - - - + + + + + + + - - + + @@ -53,12 +57,25 @@ + + + + + + + + + DependsOnTargets="GetBuildInputCacheFile" + Inputs="@(TSFiles);$(BaseIntermediateOutputPath)tsfiles.cache" + Outputs="@(BuildOutputFiles)"> - + @@ -73,7 +90,10 @@ - + + <_PackageTargetPath>$(MSBuildProjectDirectory)\$(PackageFileName) diff --git a/eng/tools/RepoTasks/RepoTasks.tasks b/eng/tools/RepoTasks/RepoTasks.tasks index 5fcc97d156..0fa015d81f 100644 --- a/eng/tools/RepoTasks/RepoTasks.tasks +++ b/eng/tools/RepoTasks/RepoTasks.tasks @@ -1,6 +1,6 @@ - <_RepoTaskAssemblyFolder Condition="'$(MSBuildRuntimeType)' == 'core'">netcoreapp3.1 + <_RepoTaskAssemblyFolder Condition="'$(MSBuildRuntimeType)' == 'core'">netcoreapp5.0 <_RepoTaskAssemblyFolder Condition="'$(MSBuildRuntimeType)' != 'core'">net472 <_RepoTaskAssembly>$(ArtifactsBinDir)RepoTasks\Release\$(_RepoTaskAssemblyFolder)\RepoTasks.dll diff --git a/global.json b/global.json index 88df91565f..72dfaa34b3 100644 --- a/global.json +++ b/global.json @@ -1,9 +1,9 @@ { "sdk": { - "version": "3.1.100" + "version": "5.0.100-alpha1-015536" }, "tools": { - "dotnet": "3.1.100", + "dotnet": "5.0.100-alpha1-015752", "runtimes": { "dotnet/x64": [ "$(MicrosoftNETCoreAppInternalPackageVersion)" @@ -15,7 +15,7 @@ "Git": "2.22.0", "jdk": "11.0.3", "vs": { - "version": "16.0", + "version": "16.3", "components": [ "Microsoft.VisualStudio.Component.VC.ATL", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", @@ -25,7 +25,7 @@ }, "msbuild-sdks": { "Yarn.MSBuild": "1.15.2", - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19577.5", - "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19577.5" + "Microsoft.DotNet.Arcade.Sdk": "5.0.0-beta.20058.1", + "Microsoft.DotNet.Helix.Sdk": "5.0.0-beta.20058.1" } } diff --git a/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs b/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs index dbfa9a3dcb..79f8fea633 100644 --- a/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs +++ b/src/Analyzers/Analyzers/src/UseAuthorizationAnalyzer.cs @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Analyzers if (useRoutingItem != null && useAuthorizationItem == null) { // This looks like - // + // // app.UseAuthorization(); // ... // app.UseRouting(); @@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Analyzers if (useAuthorizationItem != null) { // This configuration looks like - // + // // app.UseRouting(); // app.UseEndpoints(...); // ... @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Analyzers // This analyzer expects MiddlewareItem instances to appear in the order in which they appear in source // which unfortunately isn't true for chained calls (the operations appear in reverse order). // We'll avoid doing any analysis in this event and rely on the runtime guardrails. - // We'll use https://github.com/aspnet/AspNetCore/issues/16648 to track addressing this in a future milestone + // We'll use https://github.com/dotnet/aspnetcore/issues/16648 to track addressing this in a future milestone return; } diff --git a/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs b/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs index ed80fa3d08..4e396cbcea 100644 --- a/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs +++ b/src/Analyzers/Analyzers/test/AnalyzerTestBase.cs @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Analyzers } // This test code needs to be updated to support distributed testing. -// See https://github.com/aspnet/AspNetCore/issues/10422 +// See https://github.com/dotnet/aspnetcore/issues/10422 #pragma warning disable 0618 var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Analyzers"); #pragma warning restore 0618 diff --git a/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj b/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj index 87d62d3fda..413d6c61bf 100644 --- a/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj +++ b/src/Analyzers/Analyzers/test/Microsoft.AspNetCore.Analyzers.Test.csproj @@ -6,7 +6,7 @@ Microsoft.AspNetCore.Analyzers - + false diff --git a/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs b/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs index fc635ef7f2..8345ddc586 100644 --- a/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs +++ b/src/Analyzers/Analyzers/test/StartupAnalyzerTest.cs @@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.Analyzers [Fact] public async Task StartupAnalyzer_UseAuthorizationConfiguredAsAChain_ReportsNoDiagnostics() { - // Regression test for https://github.com/aspnet/AspNetCore/issues/15203 + // Regression test for https://github.com/dotnet/aspnetcore/issues/15203 // Arrange var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthConfiguredCorrectlyChained)); @@ -298,7 +298,7 @@ namespace Microsoft.AspNetCore.Analyzers [Fact] public async Task StartupAnalyzer_UseAuthorizationConfiguredBeforeUseRoutingChained_ReportsDiagnostics() { - // This one asserts a false negative for https://github.com/aspnet/AspNetCore/issues/15203. + // This one asserts a false negative for https://github.com/dotnet/aspnetcore/issues/15203. // We don't correctly identify chained calls, this test verifies the behavior. // Arrange var source = Read(nameof(TestFiles.StartupAnalyzerTest.UseAuthBeforeUseRoutingChained)); diff --git a/src/Antiforgery/README.md b/src/Antiforgery/README.md index eb59611a42..59aa0da5a0 100644 --- a/src/Antiforgery/README.md +++ b/src/Antiforgery/README.md @@ -3,4 +3,4 @@ Antiforgery Antiforgery system for generating secure tokens to prevent Cross-Site Request Forgery attacks. -This project is part of ASP.NET Core. You can find documentation and getting started instructions for ASP.NET Core at the [AspNetCore](https://github.com/aspnet/AspNetCore) repo. +This project is part of ASP.NET Core. You can find documentation and getting started instructions for ASP.NET Core at the [AspNetCore](https://github.com/dotnet/aspnetcore) repo. diff --git a/src/Antiforgery/ref/Microsoft.AspNetCore.Antiforgery.netcoreapp.cs b/src/Antiforgery/ref/Microsoft.AspNetCore.Antiforgery.netcoreapp.cs index 5eb2c8be65..4ca6748cce 100644 --- a/src/Antiforgery/ref/Microsoft.AspNetCore.Antiforgery.netcoreapp.cs +++ b/src/Antiforgery/ref/Microsoft.AspNetCore.Antiforgery.netcoreapp.cs @@ -9,16 +9,16 @@ namespace Microsoft.AspNetCore.Antiforgery public AntiforgeryOptions() { } public Microsoft.AspNetCore.Http.CookieBuilder Cookie { get { throw null; } set { } } public string FormFieldName { get { throw null; } set { } } - public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressXFrameOptionsHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressXFrameOptionsHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class AntiforgeryTokenSet { public AntiforgeryTokenSet(string requestToken, string cookieToken, string formFieldName, string headerName) { } - public string CookieToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string FormFieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RequestToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string CookieToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string FormFieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RequestToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class AntiforgeryValidationException : System.Exception { diff --git a/src/Antiforgery/src/IAntiforgeryAdditionalDataProvider.cs b/src/Antiforgery/src/IAntiforgeryAdditionalDataProvider.cs index d66b6245db..485fc8c9e8 100644 --- a/src/Antiforgery/src/IAntiforgeryAdditionalDataProvider.cs +++ b/src/Antiforgery/src/IAntiforgeryAdditionalDataProvider.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Antiforgery /// /// Allows providing or validating additional custom data for antiforgery tokens. /// For example, the developer could use this to supply a nonce when the token is - /// generated, then he could validate the nonce when the token is validated. + /// generated, then validate it when the token is validated. /// /// /// The antiforgery system already embeds the client's username within the diff --git a/src/Antiforgery/src/Internal/BinaryBlob.cs b/src/Antiforgery/src/Internal/BinaryBlob.cs index 0e5039295a..9313175b36 100644 --- a/src/Antiforgery/src/Internal/BinaryBlob.cs +++ b/src/Antiforgery/src/Internal/BinaryBlob.cs @@ -15,7 +15,6 @@ namespace Microsoft.AspNetCore.Antiforgery [DebuggerDisplay("{DebuggerString}")] internal sealed class BinaryBlob : IEquatable { - private static readonly RandomNumberGenerator _randomNumberGenerator = RandomNumberGenerator.Create(); private readonly byte[] _data; // Generates a new token using a specified bit length. @@ -92,7 +91,7 @@ namespace Microsoft.AspNetCore.Antiforgery private static byte[] GenerateNewToken(int bitLength) { var data = new byte[bitLength / 8]; - _randomNumberGenerator.GetBytes(data); + RandomNumberGenerator.Fill(data); return data; } diff --git a/src/Antiforgery/src/Internal/DefaultAntiforgery.cs b/src/Antiforgery/src/Internal/DefaultAntiforgery.cs index 030f79c07e..f88d18bf8a 100644 --- a/src/Antiforgery/src/Internal/DefaultAntiforgery.cs +++ b/src/Antiforgery/src/Internal/DefaultAntiforgery.cs @@ -102,10 +102,10 @@ namespace Microsoft.AspNetCore.Antiforgery CheckSSLConfig(httpContext); var method = httpContext.Request.Method; - if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase) || - string.Equals(method, "HEAD", StringComparison.OrdinalIgnoreCase) || - string.Equals(method, "OPTIONS", StringComparison.OrdinalIgnoreCase) || - string.Equals(method, "TRACE", StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsGet(method) || + HttpMethods.IsHead(method) || + HttpMethods.IsOptions(method) || + HttpMethods.IsTrace(method)) { // Validation not needed for these request types. return true; @@ -379,7 +379,7 @@ namespace Microsoft.AspNetCore.Antiforgery /// The . protected virtual void SetDoNotCacheHeaders(HttpContext httpContext) { - // Since antifogery token generation is not very obvious to the end users (ex: MVC's form tag generates them + // Since antiforgery token generation is not very obvious to the end users (ex: MVC's form tag generates them // by default), log a warning to let users know of the change in behavior to any cache headers they might // have set explicitly. LogCacheHeaderOverrideWarning(httpContext.Response); diff --git a/src/Antiforgery/test/DefaultAntiforgeryTokenGeneratorTest.cs b/src/Antiforgery/test/DefaultAntiforgeryTokenGeneratorTest.cs index e32fbb85ab..3df264d48d 100644 --- a/src/Antiforgery/test/DefaultAntiforgeryTokenGeneratorTest.cs +++ b/src/Antiforgery/test/DefaultAntiforgeryTokenGeneratorTest.cs @@ -149,10 +149,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal httpContext.User = new ClaimsPrincipal(identity); byte[] data = new byte[256 / 8]; - using (var rng = RandomNumberGenerator.Create()) - { - rng.GetBytes(data); - } + RandomNumberGenerator.Fill(data); var base64ClaimUId = Convert.ToBase64String(data); var expectedClaimUid = new BinaryBlob(256, data); diff --git a/src/Antiforgery/test/DefaultClaimUidExtractorTest.cs b/src/Antiforgery/test/DefaultClaimUidExtractorTest.cs index 1852b910da..67d690a83a 100644 --- a/src/Antiforgery/test/DefaultClaimUidExtractorTest.cs +++ b/src/Antiforgery/test/DefaultClaimUidExtractorTest.cs @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public void DefaultUniqueClaimTypes_NotPresent_SerializesAllClaimTypes() { var identity = new ClaimsIdentity("someAuthentication"); - identity.AddClaim(new Claim(ClaimTypes.Email, "someone@antifrogery.com")); + identity.AddClaim(new Claim(ClaimTypes.Email, "someone@antiforgery.com")); identity.AddClaim(new Claim(ClaimTypes.GivenName, "some")); identity.AddClaim(new Claim(ClaimTypes.Surname, "one")); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, string.Empty)); diff --git a/src/Azure/AzureAD/Authentication.AzureAD.UI/ref/Microsoft.AspNetCore.Authentication.AzureAD.UI.netcoreapp.cs b/src/Azure/AzureAD/Authentication.AzureAD.UI/ref/Microsoft.AspNetCore.Authentication.AzureAD.UI.netcoreapp.cs index 2e7a9b87f9..37f4cd5573 100644 --- a/src/Azure/AzureAD/Authentication.AzureAD.UI/ref/Microsoft.AspNetCore.Authentication.AzureAD.UI.netcoreapp.cs +++ b/src/Azure/AzureAD/Authentication.AzureAD.UI/ref/Microsoft.AspNetCore.Authentication.AzureAD.UI.netcoreapp.cs @@ -26,16 +26,16 @@ namespace Microsoft.AspNetCore.Authentication.AzureAD.UI { public AzureADOptions() { } public string[] AllSchemes { get { throw null; } } - public string CallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string CookieSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string JwtBearerSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string OpenIdConnectSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignedOutCallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string TenantId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string CallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string CookieSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string JwtBearerSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string OpenIdConnectSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignedOutCallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string TenantId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Authentication.AzureAD.UI.Internal @@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Authentication.AzureAD.UI.Internal public partial class ErrorModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public ErrorModel() { } - public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool ShowRequestId { get { throw null; } } public void OnGet() { } } diff --git a/src/Azure/AzureAD/Authentication.AzureADB2C.UI/ref/Microsoft.AspNetCore.Authentication.AzureADB2C.UI.netcoreapp.cs b/src/Azure/AzureAD/Authentication.AzureADB2C.UI/ref/Microsoft.AspNetCore.Authentication.AzureADB2C.UI.netcoreapp.cs index 5cd9f38724..65981fe5fa 100644 --- a/src/Azure/AzureAD/Authentication.AzureADB2C.UI/ref/Microsoft.AspNetCore.Authentication.AzureADB2C.UI.netcoreapp.cs +++ b/src/Azure/AzureAD/Authentication.AzureADB2C.UI/ref/Microsoft.AspNetCore.Authentication.AzureADB2C.UI.netcoreapp.cs @@ -27,19 +27,19 @@ namespace Microsoft.AspNetCore.Authentication.AzureADB2C.UI { public AzureADB2COptions() { } public string[] AllSchemes { get { throw null; } } - public string CallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string CookieSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string CallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string CookieSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string DefaultPolicy { get { throw null; } } - public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EditProfilePolicyId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string JwtBearerSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string OpenIdConnectSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ResetPasswordPolicyId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignedOutCallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignUpSignInPolicyId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EditProfilePolicyId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string JwtBearerSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string OpenIdConnectSchemeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ResetPasswordPolicyId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignedOutCallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignUpSignInPolicyId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Authentication.AzureADB2C.UI.Internal @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Authentication.AzureADB2C.UI.Internal public partial class ErrorModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public ErrorModel() { } - public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool ShowRequestId { get { throw null; } } public void OnGet() { } } diff --git a/src/Azure/AzureAD/test/FunctionalTests/Microsoft.AspNetCore.Authentication.AzureAD.FunctionalTests.csproj b/src/Azure/AzureAD/test/FunctionalTests/Microsoft.AspNetCore.Authentication.AzureAD.FunctionalTests.csproj index d2cb51194b..10e3e402cc 100644 --- a/src/Azure/AzureAD/test/FunctionalTests/Microsoft.AspNetCore.Authentication.AzureAD.FunctionalTests.csproj +++ b/src/Azure/AzureAD/test/FunctionalTests/Microsoft.AspNetCore.Authentication.AzureAD.FunctionalTests.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - + true diff --git a/src/Components/Analyzers/src/ComponentInternalUsageDiagnosticAnalzyer.cs b/src/Components/Analyzers/src/ComponentInternalUsageDiagnosticAnalzyer.cs index 8f6272c326..b1b5724cb3 100644 --- a/src/Components/Analyzers/src/ComponentInternalUsageDiagnosticAnalzyer.cs +++ b/src/Components/Analyzers/src/ComponentInternalUsageDiagnosticAnalzyer.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Immutable; using Microsoft.AspNetCore.Components.Analyzers; using Microsoft.CodeAnalysis; @@ -15,6 +16,8 @@ namespace Microsoft.Extensions.Internal [DiagnosticAnalyzer(LanguageNames.CSharp)] public class ComponentInternalUsageDiagnosticAnalyzer : DiagnosticAnalyzer { + private static readonly string[] NamespaceParts = new[] { "RenderTree", "Components", "AspNetCore", "Microsoft", }; + private readonly InternalUsageAnalyzer _inner; public ComponentInternalUsageDiagnosticAnalyzer() @@ -27,17 +30,25 @@ namespace Microsoft.Extensions.Internal public override void Initialize(AnalysisContext context) { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); + _inner.Register(context); } private static bool IsInInternalNamespace(ISymbol symbol) { - if (symbol?.ContainingNamespace?.ToDisplayString() is string ns) + var @namespace = symbol?.ContainingNamespace; + for (var i = 0; i < NamespaceParts.Length; i++) { - return string.Equals(ns, "Microsoft.AspNetCore.Components.RenderTree"); + if (@namespace == null || !string.Equals(NamespaceParts[i], @namespace.Name, StringComparison.Ordinal)) + { + return false; + } + + @namespace = @namespace.ContainingNamespace; } - return false; + return @namespace.IsGlobalNamespace; } } } diff --git a/src/Components/Analyzers/src/DiagnosticDescriptors.cs b/src/Components/Analyzers/src/DiagnosticDescriptors.cs index 8eb86b3212..05b98d3b4a 100644 --- a/src/Components/Analyzers/src/DiagnosticDescriptors.cs +++ b/src/Components/Analyzers/src/DiagnosticDescriptors.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers // Note: The Razor Compiler (including Components features) use the RZ prefix for diagnostics, so there's currently // no change of clashing between that and the BL prefix used here. // - // Tracking https://github.com/aspnet/AspNetCore/issues/10382 to rationalize this + // Tracking https://github.com/dotnet/aspnetcore/issues/10382 to rationalize this public static readonly DiagnosticDescriptor ComponentParameterSettersShouldBePublic = new DiagnosticDescriptor( "BL0001", new LocalizableResourceString(nameof(Resources.ComponentParameterSettersShouldBePublic_Title), Resources.ResourceManager, typeof(Resources)), diff --git a/src/Components/Analyzers/src/InternalUsageAnalyzer.cs b/src/Components/Analyzers/src/InternalUsageAnalyzer.cs index 92b07a7ab2..495e4c90fa 100644 --- a/src/Components/Analyzers/src/InternalUsageAnalyzer.cs +++ b/src/Components/Analyzers/src/InternalUsageAnalyzer.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; namespace Microsoft.Extensions.Internal { @@ -35,87 +35,149 @@ namespace Microsoft.Extensions.Internal public void Register(AnalysisContext context) { context.EnableConcurrentExecution(); - context.RegisterSyntaxNodeAction(AnalyzeNode, - SyntaxKind.SimpleMemberAccessExpression, - SyntaxKind.ObjectCreationExpression, - SyntaxKind.ClassDeclaration, - SyntaxKind.Parameter); + + // Analyze usage of our internal types in method bodies. + context.RegisterOperationAction( + AnalyzeOperation, + OperationKind.ObjectCreation, + OperationKind.Invocation, + OperationKind.FieldReference, + OperationKind.MethodReference, + OperationKind.PropertyReference, + OperationKind.EventReference); + + // Analyze declarations that use our internal types in API surface. + context.RegisterSymbolAction( + AnalyzeSymbol, + SymbolKind.NamedType, + SymbolKind.Field, + SymbolKind.Method, + SymbolKind.Property, + SymbolKind.Event); } - private void AnalyzeNode(SyntaxNodeAnalysisContext context) + private void AnalyzeOperation(OperationAnalysisContext context) { - switch (context.Node) + var symbol = context.Operation switch { - case MemberAccessExpressionSyntax memberAccessSyntax: + IObjectCreationOperation creation => creation.Constructor, + IInvocationOperation invocation => invocation.TargetMethod, + IFieldReferenceOperation field => field.Member, + IMethodReferenceOperation method => method.Member, + IPropertyReferenceOperation property => property.Member, + IEventReferenceOperation @event => @event.Member, + _ => throw new InvalidOperationException("Unexpected operation kind: " + context.Operation.Kind), + }; + + VisitOperationSymbol(context, symbol); + } + + private void AnalyzeSymbol(SymbolAnalysisContext context) + { + // Note: we don't currently try to detect second-order usage of these types + // like public Task GetFooAsync() { }. + // + // This probably accomplishes our goals OK for now, which are focused on use of these + // types in method bodies. + switch (context.Symbol) + { + case INamedTypeSymbol type: + VisitDeclarationSymbol(context, type.BaseType, type); + foreach (var @interface in type.Interfaces) { - if (context.SemanticModel.GetSymbolInfo(context.Node, context.CancellationToken).Symbol is ISymbol symbol && - symbol.ContainingAssembly != context.Compilation.Assembly) - { - var containingType = symbol.ContainingType; + VisitDeclarationSymbol(context, @interface, type); + } + break; - if (HasInternalAttribute(symbol)) - { - context.ReportDiagnostic(Diagnostic.Create(_descriptor, memberAccessSyntax.Name.GetLocation(), $"{containingType}.{symbol.Name}")); - return; - } + case IFieldSymbol field: + VisitDeclarationSymbol(context, field.Type, field); + break; - if (IsInInternalNamespace(containingType) || HasInternalAttribute(containingType)) - { - context.ReportDiagnostic(Diagnostic.Create(_descriptor, memberAccessSyntax.Name.GetLocation(), containingType)); - return; - } - } - return; + case IMethodSymbol method: + + // Ignore return types on property-getters. Those will be reported through + // the property analysis. + if (method.MethodKind != MethodKind.PropertyGet) + { + VisitDeclarationSymbol(context, method.ReturnType, method); } - case ObjectCreationExpressionSyntax creationSyntax: + // Ignore parameters on property-setters. Those will be reported through + // the property analysis. + if (method.MethodKind != MethodKind.PropertySet) { - if (context.SemanticModel.GetSymbolInfo(context.Node, context.CancellationToken).Symbol is ISymbol symbol && - symbol.ContainingAssembly != context.Compilation.Assembly) + foreach (var parameter in method.Parameters) { - var containingType = symbol.ContainingType; - - if (HasInternalAttribute(symbol)) - { - context.ReportDiagnostic(Diagnostic.Create(_descriptor, creationSyntax.GetLocation(), containingType)); - return; - } - - if (IsInInternalNamespace(containingType) || HasInternalAttribute(containingType)) - { - context.ReportDiagnostic(Diagnostic.Create(_descriptor, creationSyntax.Type.GetLocation(), containingType)); - return; - } + VisitDeclarationSymbol(context, parameter.Type, method); } - - return; } + break; - case ClassDeclarationSyntax declarationSyntax: - { - if (context.SemanticModel.GetDeclaredSymbol(declarationSyntax)?.BaseType is ISymbol symbol && - symbol.ContainingAssembly != context.Compilation.Assembly && - (IsInInternalNamespace(symbol) || HasInternalAttribute(symbol)) && - declarationSyntax.BaseList?.Types.Count > 0) - { - context.ReportDiagnostic(Diagnostic.Create(_descriptor, declarationSyntax.BaseList.Types[0].GetLocation(), symbol)); - } + case IPropertySymbol property: + VisitDeclarationSymbol(context, property.Type, property); + break; - return; - } + case IEventSymbol @event: + VisitDeclarationSymbol(context, @event.Type, @event); + break; + } + } - case ParameterSyntax parameterSyntax: - { - if (context.SemanticModel.GetDeclaredSymbol(parameterSyntax)?.Type is ISymbol symbol && - symbol.ContainingAssembly != context.Compilation.Assembly && - (IsInInternalNamespace(symbol) || HasInternalAttribute(symbol))) - { + // Similar logic here to VisitDeclarationSymbol, keep these in sync. + private void VisitOperationSymbol(OperationAnalysisContext context, ISymbol symbol) + { + if (symbol.ContainingAssembly == context.Compilation.Assembly) + { + // The type is being referenced within the same assembly. This is valid use of an "internal" type + return; + } - context.ReportDiagnostic(Diagnostic.Create(_descriptor, parameterSyntax.GetLocation(), symbol)); - } + if (HasInternalAttribute(symbol)) + { + context.ReportDiagnostic(Diagnostic.Create( + _descriptor, + context.Operation.Syntax.GetLocation(), + symbol.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat))); + return; + } - return; - } + var containingType = symbol.ContainingType; + if (IsInInternalNamespace(containingType) || HasInternalAttribute(containingType)) + { + context.ReportDiagnostic(Diagnostic.Create( + _descriptor, + context.Operation.Syntax.GetLocation(), + containingType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat))); + return; + } + } + + // Similar logic here to VisitOperationSymbol, keep these in sync. + private void VisitDeclarationSymbol(SymbolAnalysisContext context, ISymbol symbol, ISymbol symbolForDiagnostic) + { + if (symbol.ContainingAssembly == context.Compilation.Assembly) + { + // This is part of the compilation, avoid this analyzer when building from source. + return; + } + + if (HasInternalAttribute(symbol)) + { + context.ReportDiagnostic(Diagnostic.Create( + _descriptor, + symbolForDiagnostic.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation() ?? Location.None, + symbol.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat))); + return; + } + + var containingType = symbol as INamedTypeSymbol ?? symbol.ContainingType; + if (IsInInternalNamespace(containingType) || HasInternalAttribute(containingType)) + { + context.ReportDiagnostic(Diagnostic.Create( + _descriptor, + symbolForDiagnostic.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax().GetLocation() ?? Location.None, + containingType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat))); + return; } } diff --git a/src/Components/Analyzers/test/AnalyzerTestBase.cs b/src/Components/Analyzers/test/AnalyzerTestBase.cs index 8c1ae95376..91bfe2d9cc 100644 --- a/src/Components/Analyzers/test/AnalyzerTestBase.cs +++ b/src/Components/Analyzers/test/AnalyzerTestBase.cs @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Components.Analyzers } // This test code needs to be updated to support distributed testing. - // See https://github.com/aspnet/AspNetCore/issues/10422 + // See https://github.com/dotnet/aspnetcore/issues/10422 #pragma warning disable 0618 var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Components"); #pragma warning restore 0618 diff --git a/src/Components/Analyzers/test/ComponentInternalUsageDiagnosticsAnalyzerTest.cs b/src/Components/Analyzers/test/ComponentInternalUsageDiagnosticsAnalyzerTest.cs new file mode 100644 index 0000000000..c7a01a5c63 --- /dev/null +++ b/src/Components/Analyzers/test/ComponentInternalUsageDiagnosticsAnalyzerTest.cs @@ -0,0 +1,105 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Analyzer.Testing; +using Microsoft.Extensions.Internal; +using Xunit; + +namespace Microsoft.AspNetCore.Components.Analyzers +{ + public class ComponentInternalUsageDiagnosticsAnalyzerTest : AnalyzerTestBase + { + public ComponentInternalUsageDiagnosticsAnalyzerTest() + { + Analyzer = new ComponentInternalUsageDiagnosticAnalyzer(); + Runner = new ComponentAnalyzerDiagnosticAnalyzerRunner(Analyzer); + } + + private ComponentInternalUsageDiagnosticAnalyzer Analyzer { get; } + private ComponentAnalyzerDiagnosticAnalyzerRunner Runner { get; } + + [Fact] + public async Task InternalUsage_FindsUseOfInternalTypesInDeclarations() + { + // Arrange + var source = Read("UsesRendererTypesInDeclarations"); + + // Act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + + // Assert + Assert.Collection( + diagnostics, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMBaseClass"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMField"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMInvocation"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMProperty"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMParameter"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMReturnType"], diagnostic.Location); + }); + } + + [Fact] + public async Task InternalUsage_FindsUseOfInternalTypesInMethodBody() + { + // Arrange + var source = Read("UsersRendererTypesInMethodBody"); + + // Act + var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); + + // Assert + Assert.Collection( + diagnostics, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMField"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMNewObject"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMProperty"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMNewObject2"], diagnostic.Location); + }, + diagnostic => + { + Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); + AnalyzerAssert.DiagnosticLocation(source.MarkerLocations["MMInvocation"], diagnostic.Location); + }); + } + } +} diff --git a/src/Components/Analyzers/test/ComponentInternalUsageDiagnoticsAnalyzerTest.cs b/src/Components/Analyzers/test/ComponentInternalUsageDiagnoticsAnalyzerTest.cs deleted file mode 100644 index 92e2252304..0000000000 --- a/src/Components/Analyzers/test/ComponentInternalUsageDiagnoticsAnalyzerTest.cs +++ /dev/null @@ -1,60 +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. - -using System.Threading.Tasks; -using Microsoft.AspNetCore.Analyzer.Testing; -using Microsoft.Extensions.Internal; -using Xunit; - -namespace Microsoft.AspNetCore.Components.Analyzers -{ - public class ComponentInternalUsageDiagnoticsAnalyzerTest : AnalyzerTestBase - { - public ComponentInternalUsageDiagnoticsAnalyzerTest() - { - Analyzer = new ComponentInternalUsageDiagnosticAnalyzer(); - Runner = new ComponentAnalyzerDiagnosticAnalyzerRunner(Analyzer); - } - - private ComponentInternalUsageDiagnosticAnalyzer Analyzer { get; } - private ComponentAnalyzerDiagnosticAnalyzerRunner Runner { get; } - - [Fact] - public async Task InternalUsage_FindsUseOfRenderTreeFrameAsParameter() - { - // Arrange - var source = Read("UsesRenderTreeFrameAsParameter"); - - // Act - var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); - - // Assert - Assert.Collection( - diagnostics, - diagnostic => - { - Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); - AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); - }); - } - - [Fact] - public async Task InternalUsage_FindsUseOfRenderTreeType() - { - // Arrange - var source = Read("UsesRenderTreeFrameTypeAsLocal"); - - // Act - var diagnostics = await Runner.GetDiagnosticsAsync(source.Source); - - // Assert - Assert.Collection( - diagnostics, - diagnostic => - { - Assert.Same(DiagnosticDescriptors.DoNotUseRenderTreeTypes, diagnostic.Descriptor); - AnalyzerAssert.DiagnosticLocation(source.DefaultMarkerLocation, diagnostic.Location); - }); - } - } -} diff --git a/src/Components/Analyzers/test/Microsoft.AspNetCore.Components.Analyzers.Tests.csproj b/src/Components/Analyzers/test/Microsoft.AspNetCore.Components.Analyzers.Tests.csproj index 10085017d1..8becc8014b 100644 --- a/src/Components/Analyzers/test/Microsoft.AspNetCore.Components.Analyzers.Tests.csproj +++ b/src/Components/Analyzers/test/Microsoft.AspNetCore.Components.Analyzers.Tests.csproj @@ -4,7 +4,7 @@ $(DefaultNetCoreTargetFramework) - + false diff --git a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsersRendererTypesInMethodBody.cs b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsersRendererTypesInMethodBody.cs new file mode 100644 index 0000000000..9bd27fb960 --- /dev/null +++ b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsersRendererTypesInMethodBody.cs @@ -0,0 +1,20 @@ +using System; +using Microsoft.AspNetCore.Components.RenderTree; + +namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInternalUsageDiagnosticsAnalyzerTest +{ + class UsersRendererTypesInMethodBody + { + private void Test() + { + var test = /*MMField*/RenderTreeFrameType.Attribute; + GC.KeepAlive(test); + + var frame = /*MMNewObject*/new RenderTreeFrame(); + GC.KeepAlive(/*MMProperty*/frame.Component); + + var range = /*MMNewObject2*/new ArrayRange(null, 0); + /*MMInvocation*/range.Clone(); + } + } +} diff --git a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsesRendererAsBaseClass.cs b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsesRendererAsBaseClass.cs new file mode 100644 index 0000000000..7ca9dfccf5 --- /dev/null +++ b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsesRendererAsBaseClass.cs @@ -0,0 +1,26 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.RenderTree; + +namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInternalUsageDiagnosticsAnalyzerTest +{ + /*MM*/class UsesRendererAsBaseClass : Renderer + { + public UsesRendererAsBaseClass() + : base(null, null) + { + } + + public override Dispatcher Dispatcher => throw new NotImplementedException(); + + protected override void HandleException(Exception exception) + { + throw new NotImplementedException(); + } + + protected override Task UpdateDisplayAsync(/*M1*/in RenderBatch renderBatch) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsesRendererTypesInDeclarations.cs b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsesRendererTypesInDeclarations.cs new file mode 100644 index 0000000000..e2877b0df5 --- /dev/null +++ b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnosticsAnalyzerTest/UsesRendererTypesInDeclarations.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components.RenderTree; + +namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInternalUsageDiagnosticsAnalyzerTest +{ + /*MMBaseClass*/class UsesRendererTypesInDeclarations : Renderer + { + private Renderer /*MMField*/_field = null; + + public UsesRendererTypesInDeclarations() + /*MMInvocation*/: base(null, null) + { + } + + public override Dispatcher Dispatcher => throw new NotImplementedException(); + + /*MMProperty*/public Renderer Property { get; set; } + + protected override void HandleException(Exception exception) + { + throw new NotImplementedException(); + } + + /*MMParameter*/protected override Task UpdateDisplayAsync(in RenderBatch renderBatch) + { + throw new NotImplementedException(); + } + + /*MMReturnType*/private Renderer GetRenderer() => _field; + } +} diff --git a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnoticsAnalyzerTest/UsesRenderTreeFrameAsParameter.cs b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnoticsAnalyzerTest/UsesRenderTreeFrameAsParameter.cs deleted file mode 100644 index 415030a011..0000000000 --- a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnoticsAnalyzerTest/UsesRenderTreeFrameAsParameter.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Components.RenderTree; - -namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInternalUsageDiagnoticsAnalyzerTest -{ - class UsesRenderTreeFrameAsParameter - { - private void Test(/*MM*/RenderTreeFrame frame) - { - } - } -} diff --git a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnoticsAnalyzerTest/UsesRenderTreeFrameTypeAsLocal.cs b/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnoticsAnalyzerTest/UsesRenderTreeFrameTypeAsLocal.cs deleted file mode 100644 index bdd40c2df1..0000000000 --- a/src/Components/Analyzers/test/TestFiles/ComponentInternalUsageDiagnoticsAnalyzerTest/UsesRenderTreeFrameTypeAsLocal.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using Microsoft.AspNetCore.Components.RenderTree; - -namespace Microsoft.AspNetCore.Components.Analyzers.Tests.TestFiles.ComponentInternalUsageDiagnoticsAnalyzerTest -{ - class UsesRenderTreeFrameTypeAsLocal - { - private void Test() - { - var test = RenderTreeFrameType./*MM*/Attribute; - GC.KeepAlive(test); - } - - } -} diff --git a/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netcoreapp.cs b/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netcoreapp.cs index ca0535937a..1ed5ecbf0e 100644 --- a/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netcoreapp.cs +++ b/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netcoreapp.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Components.Authorization public partial class AuthenticationState { public AuthenticationState(System.Security.Claims.ClaimsPrincipal user) { } - public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public delegate void AuthenticationStateChangedHandler(System.Threading.Tasks.Task task); public abstract partial class AuthenticationStateProvider @@ -20,33 +20,33 @@ namespace Microsoft.AspNetCore.Components.Authorization { public AuthorizeRouteView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void Render(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } } public partial class AuthorizeView : Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore { public AuthorizeView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override Microsoft.AspNetCore.Authorization.IAuthorizeData[] GetAuthorizeData() { throw null; } } public abstract partial class AuthorizeViewCore : Microsoft.AspNetCore.Components.ComponentBase { protected AuthorizeViewCore() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Authorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Authorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected abstract Microsoft.AspNetCore.Authorization.IAuthorizeData[] GetAuthorizeData(); [System.Diagnostics.DebuggerStepThroughAttribute] @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Components.Authorization { public CascadingAuthenticationState() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { } protected override void OnInitialized() { } void System.IDisposable.Dispose() { } diff --git a/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netstandard2.0.cs b/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netstandard2.0.cs index ca0535937a..1ed5ecbf0e 100644 --- a/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netstandard2.0.cs +++ b/src/Components/Authorization/ref/Microsoft.AspNetCore.Components.Authorization.netstandard2.0.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Components.Authorization public partial class AuthenticationState { public AuthenticationState(System.Security.Claims.ClaimsPrincipal user) { } - public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public delegate void AuthenticationStateChangedHandler(System.Threading.Tasks.Task task); public abstract partial class AuthenticationStateProvider @@ -20,33 +20,33 @@ namespace Microsoft.AspNetCore.Components.Authorization { public AuthorizeRouteView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void Render(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } } public partial class AuthorizeView : Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore { public AuthorizeView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override Microsoft.AspNetCore.Authorization.IAuthorizeData[] GetAuthorizeData() { throw null; } } public abstract partial class AuthorizeViewCore : Microsoft.AspNetCore.Components.ComponentBase { protected AuthorizeViewCore() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Authorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Authorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Authorizing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment NotAuthorized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected abstract Microsoft.AspNetCore.Authorization.IAuthorizeData[] GetAuthorizeData(); [System.Diagnostics.DebuggerStepThroughAttribute] @@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Components.Authorization { public CascadingAuthenticationState() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { } protected override void OnInitialized() { } void System.IDisposable.Dispose() { } diff --git a/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs b/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs index b8062d72c0..583e9efc50 100644 --- a/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs +++ b/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Blazor.Hosting public sealed partial class WebAssemblyHostBuilderContext { public WebAssemblyHostBuilderContext(System.Collections.Generic.IDictionary properties) { } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class WebAssemblyHostBuilderExtensions { diff --git a/src/Components/Blazor/Blazor/src/Hosting/IWebAssemblyServiceFactoryAdapter.cs b/src/Components/Blazor/Blazor/src/Hosting/IWebAssemblyServiceFactoryAdapter.cs index c790a3c879..ff63ec3a66 100644 --- a/src/Components/Blazor/Blazor/src/Hosting/IWebAssemblyServiceFactoryAdapter.cs +++ b/src/Components/Blazor/Blazor/src/Hosting/IWebAssemblyServiceFactoryAdapter.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Blazor.Hosting { - // Equivalent to https://github.com/aspnet/Extensions/blob/master/src/Hosting/Hosting/src/Internal/IServiceFactoryAdapter.cs + // Equivalent to https://github.com/dotnet/extensions/blob/master/src/Hosting/Hosting/src/Internal/IServiceFactoryAdapter.cs internal interface IWebAssemblyServiceFactoryAdapter { diff --git a/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostExtensions.cs b/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostExtensions.cs index d08162a590..5182a1660d 100644 --- a/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostExtensions.cs +++ b/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostExtensions.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Blazor.Hosting public static void Run(this IWebAssemblyHost host) { // Behave like async void, because we don't yet support async-main properly on WebAssembly. - // However, don't actualy make this method async, because we rely on startup being synchronous + // However, don't actually make this method async, because we rely on startup being synchronous // for things like attaching navigation event handlers. host.StartAsync().ContinueWith(task => { diff --git a/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyServiceFactoryAdapter.cs b/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyServiceFactoryAdapter.cs index fcc879653a..2cfc0ba093 100644 --- a/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyServiceFactoryAdapter.cs +++ b/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyServiceFactoryAdapter.cs @@ -6,7 +6,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Blazor.Hosting { - // Equivalent to https://github.com/aspnet/Extensions/blob/master/src/Hosting/Hosting/src/Internal/ServiceFactoryAdapter.cs + // Equivalent to https://github.com/dotnet/extensions/blob/master/src/Hosting/Hosting/src/Internal/ServiceFactoryAdapter.cs internal class WebAssemblyServiceFactoryAdapter : IWebAssemblyServiceFactoryAdapter { diff --git a/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs b/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs index c86c1cf30b..1769dbd915 100644 --- a/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs +++ b/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs @@ -20,6 +20,11 @@ namespace Microsoft.AspNetCore.Blazor.Services public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { + if (!IsEnabled(logLevel)) + { + return; + } + var formattedMessage = formatter(state, exception); Console.WriteLine($"[{logLevel}] {formattedMessage}"); } diff --git a/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml b/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml index 3275831dca..6f36c72089 100644 --- a/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml +++ b/src/Components/Blazor/Build/src/targets/BuiltInBclLinkerDescriptor.xml @@ -2,11 +2,11 @@ + described at https://github.com/mono/linker/blob/master/src/linker/README.md#syntax-of-xml-descriptor --> + to implement timers. Fixes https://github.com/dotnet/blazor/issues/239 --> diff --git a/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs index 1fafb9e81d..2292df38d8 100644 --- a/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs +++ b/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs @@ -448,7 +448,7 @@ namespace Test frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 4)); } - [Fact] // See https://github.com/aspnet/Blazor/issues/703 + [Fact] // See https://github.com/dotnet/blazor/issues/703 public void Workaround_703() { // Arrange diff --git a/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs b/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs index 1cc39f0d6e..dbc8aff929 100644 --- a/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs +++ b/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Blazor.Build { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = "netcoreapp3.1"; + project.TargetFramework = "netcoreapp5.0"; var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); diff --git a/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs b/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs index 6995ffde4d..59dc691c0c 100644 --- a/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs +++ b/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Blazor.Build Assert.FileExists(result, blazorPublishDirectory, "dist", "index.html"); // Verify static web assets from referenced projects are copied. - // Uncomment once https://github.com/aspnet/AspNetCore/issues/17426 is resolved. + // Uncomment once https://github.com/dotnet/aspnetcore/issues/17426 is resolved. // Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); // Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "styles.css"); @@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.Blazor.Build { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = "netcoreapp3.1"; + project.TargetFramework = "netcoreapp5.0"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); @@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.Blazor.Build { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = "netcoreapp3.1"; + project.TargetFramework = "netcoreapp5.0"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); Assert.BuildPassed(result); @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.Blazor.Build Assert.FileExists(result, blazorPublishDirectory, "dist", "index.html"); // Verify static web assets from referenced projects are copied. - // Uncomment once https://github.com/aspnet/AspNetCore/issues/17426 is resolved. + // Uncomment once https://github.com/dotnet/aspnetcore/issues/17426 is resolved. // Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); // Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); diff --git a/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs index d15cf4f584..f4a45c7e2f 100644 --- a/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs +++ b/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs @@ -96,7 +96,7 @@ namespace Test } [Fact] - public void Render_ChildComponent_TriesToSetNonParamter() + public void Render_ChildComponent_TriesToSetNonParameter() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" @@ -408,7 +408,7 @@ namespace Test frame => AssertFrame.Text(frame, "Some text", 4)); } - [Fact] // https://github.com/aspnet/Blazor/issues/773 + [Fact] // https://github.com/dotnet/blazor/issues/773 public void Regression_773() { // Arrange @@ -470,7 +470,7 @@ namespace Test frame => AssertFrame.Attribute(frame, "style", "background: #FFFFFF;", 2)); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/6185")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/6185")] public void Render_Component_HtmlEncoded() { // Arrange @@ -501,7 +501,7 @@ namespace Test } // Integration test for HTML block rewriting - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/6183")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/6183")] public void Render_HtmlBlock_Integration() { // Arrange diff --git a/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj b/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj index 652888d604..25b791e22a 100644 --- a/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj +++ b/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj @@ -5,6 +5,7 @@ $(DefaultItemExcludes);TestFiles\**\* + false diff --git a/src/Components/Blazor/Build/test/RuntimeDependenciesResolverTest.cs b/src/Components/Blazor/Build/test/RuntimeDependenciesResolverTest.cs index 951b1a61df..64aad9bf45 100644 --- a/src/Components/Blazor/Build/test/RuntimeDependenciesResolverTest.cs +++ b/src/Components/Blazor/Build/test/RuntimeDependenciesResolverTest.cs @@ -13,8 +13,8 @@ namespace Microsoft.AspNetCore.Blazor.Build { public class RuntimeDependenciesResolverTest { - [ConditionalFact(Skip = " https://github.com/aspnet/AspNetCore/issues/12059")] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/10426")] + [ConditionalFact(Skip = " https://github.com/dotnet/aspnetcore/issues/12059")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/10426")] public void FindsReferenceAssemblyGraph_ForStandaloneApp() { // Arrange diff --git a/src/Components/Blazor/Build/testassets/Directory.Build.props b/src/Components/Blazor/Build/testassets/Directory.Build.props index cf4b11d0cf..f60dc0021d 100644 --- a/src/Components/Blazor/Build/testassets/Directory.Build.props +++ b/src/Components/Blazor/Build/testassets/Directory.Build.props @@ -7,7 +7,7 @@ $(ComponentsRoot)Blazor\Build\src\ $(BlazorBuildRoot)ReferenceBlazorBuildFromSource.props - + netcoreapp3.1 false diff --git a/src/Components/Blazor/Build/testassets/blazorhosted/blazorhosted.csproj b/src/Components/Blazor/Build/testassets/blazorhosted/blazorhosted.csproj index 5a89588d8c..1b4127e1f4 100644 --- a/src/Components/Blazor/Build/testassets/blazorhosted/blazorhosted.csproj +++ b/src/Components/Blazor/Build/testassets/blazorhosted/blazorhosted.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + netcoreapp5.0 true diff --git a/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj b/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj index be0bd7f87b..d18ab7c9e4 100644 --- a/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj +++ b/src/Components/Blazor/DevServer/src/Microsoft.AspNetCore.Blazor.DevServer.csproj @@ -11,14 +11,15 @@ Development server for use when building Blazor applications. false - - - true + + + + diff --git a/src/Components/Blazor/Server/src/Microsoft.AspNetCore.Blazor.Server.csproj b/src/Components/Blazor/Server/src/Microsoft.AspNetCore.Blazor.Server.csproj index 0ad19d5362..ac8147d099 100644 --- a/src/Components/Blazor/Server/src/Microsoft.AspNetCore.Blazor.Server.csproj +++ b/src/Components/Blazor/Server/src/Microsoft.AspNetCore.Blazor.Server.csproj @@ -5,15 +5,18 @@ Runtime server features for ASP.NET Core Blazor applications. true false - - true - + + + + + + diff --git a/src/Components/Blazor/Server/src/MonoDebugProxy/ws-proxy/MonoProxy.cs b/src/Components/Blazor/Server/src/MonoDebugProxy/ws-proxy/MonoProxy.cs index 8c440da1ce..7aa4dcf710 100644 --- a/src/Components/Blazor/Server/src/MonoDebugProxy/ws-proxy/MonoProxy.cs +++ b/src/Components/Blazor/Server/src/MonoDebugProxy/ws-proxy/MonoProxy.cs @@ -100,7 +100,7 @@ namespace WsProxy { break; } case "Debugger.paused": { - //TODO figure out how to stich out more frames and, in particular what happens when real wasm is on the stack + //TODO figure out how to stitch out more frames and, in particular what happens when real wasm is on the stack var top_func = args? ["callFrames"]? [0]? ["functionName"]?.Value (); if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp") { await OnBreakPointHit (args, token); @@ -419,7 +419,7 @@ namespace WsProxy { var res = await SendCommand("Runtime.evaluate", o, token); - //if we fail we just buble that to the IDE (and let it panic over it) + //if we fail we just bubble that to the IDE (and let it panic over it) if (res.IsErr) { SendResponse(msg_id, res, token); @@ -475,7 +475,7 @@ namespace WsProxy { var res = await SendCommand ("Runtime.evaluate", o, token); - //if we fail we just buble that to the IDE (and let it panic over it) + //if we fail we just bubble that to the IDE (and let it panic over it) if (res.IsErr) { SendResponse (msg_id, res, token); return; @@ -594,7 +594,7 @@ namespace WsProxy { var res = await EnableBreakPoint (bp, token); var ret_code = res.Value? ["result"]? ["value"]?.Value (); - //if we fail we just buble that to the IDE (and let it panic over it) + //if we fail we just bubble that to the IDE (and let it panic over it) if (!ret_code.HasValue) { //FIXME figure out how to inform the IDE of that. Info ($"FAILED TO ENABLE BP {bp.LocalId}"); @@ -668,7 +668,7 @@ namespace WsProxy { var res = await EnableBreakPoint (bp, token); var ret_code = res.Value? ["result"]? ["value"]?.Value (); - //if we fail we just buble that to the IDE (and let it panic over it) + //if we fail we just bubble that to the IDE (and let it panic over it) if (!ret_code.HasValue) { SendResponse (msg_id, res, token); return; diff --git a/src/Components/Blazor/testassets/HostedInAspNet.Server/HostedInAspNet.Server.csproj b/src/Components/Blazor/testassets/HostedInAspNet.Server/HostedInAspNet.Server.csproj index 389b41c63f..c4ab49b06c 100644 --- a/src/Components/Blazor/testassets/HostedInAspNet.Server/HostedInAspNet.Server.csproj +++ b/src/Components/Blazor/testassets/HostedInAspNet.Server/HostedInAspNet.Server.csproj @@ -2,17 +2,16 @@ $(DefaultNetCoreTargetFramework) - - true - - + + + diff --git a/src/Components/Blazor/testassets/MonoSanity/MonoSanity.csproj b/src/Components/Blazor/testassets/MonoSanity/MonoSanity.csproj index 464f63b57c..e2158c8c06 100644 --- a/src/Components/Blazor/testassets/MonoSanity/MonoSanity.csproj +++ b/src/Components/Blazor/testassets/MonoSanity/MonoSanity.csproj @@ -3,7 +3,6 @@ $(DefaultNetCoreTargetFramework) - true @@ -11,7 +10,9 @@ + + diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs index c4a48435b4..10a26b70af 100644 --- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs +++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netcoreapp.cs @@ -54,35 +54,35 @@ namespace Microsoft.AspNetCore.Components public sealed partial class BindElementAttribute : System.Attribute { public BindElementAttribute(string element, string suffix, string valueAttribute, string changeAttribute) { } - public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Element { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Element { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public sealed partial class CascadingParameterAttribute : System.Attribute { public CascadingParameterAttribute() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CascadingValue : Microsoft.AspNetCore.Components.IComponent { public CascadingValue() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public bool IsFixed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool IsFixed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } } public partial class ChangeEventArgs : System.EventArgs { public ChangeEventArgs() { } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class ComponentBase : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, Microsoft.AspNetCore.Components.IHandleEvent { @@ -119,13 +119,15 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct ElementReference { private readonly object _dummy; + private readonly int _dummyPrimitive; public ElementReference(string id) { throw null; } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct EventCallback { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Components.EventCallback Empty; public static readonly Microsoft.AspNetCore.Components.EventCallbackFactory Factory; public EventCallback(Microsoft.AspNetCore.Components.IHandleEvent receiver, System.MulticastDelegate @delegate) { throw null; } @@ -190,6 +192,7 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct EventCallbackWorkItem { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Components.EventCallbackWorkItem Empty; public EventCallbackWorkItem(System.MulticastDelegate @delegate) { throw null; } public System.Threading.Tasks.Task InvokeAsync(object arg) { throw null; } @@ -198,6 +201,7 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct EventCallback { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Components.EventCallback Empty; public EventCallback(Microsoft.AspNetCore.Components.IHandleEvent receiver, System.MulticastDelegate @delegate) { throw null; } public bool HasDelegate { get { throw null; } } @@ -208,10 +212,10 @@ namespace Microsoft.AspNetCore.Components { public EventHandlerAttribute(string attributeName, System.Type eventArgsType) { } public EventHandlerAttribute(string attributeName, System.Type eventArgsType, bool enableStopPropagation, bool enablePreventDefault) { } - public string AttributeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnablePreventDefault { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnableStopPropagation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AttributeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnablePreventDefault { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnableStopPropagation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IComponent { @@ -235,21 +239,21 @@ namespace Microsoft.AspNetCore.Components public sealed partial class LayoutAttribute : System.Attribute { public LayoutAttribute(System.Type layoutType) { } - public System.Type LayoutType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type LayoutType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class LayoutComponentBase : Microsoft.AspNetCore.Components.ComponentBase { protected LayoutComponentBase() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class LayoutView : Microsoft.AspNetCore.Components.IComponent { public LayoutView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Type Layout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type Layout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } } @@ -261,15 +265,16 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct MarkupString { private readonly object _dummy; + private readonly int _dummyPrimitive; public MarkupString(string value) { throw null; } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static explicit operator Microsoft.AspNetCore.Components.MarkupString (string value) { throw null; } public override string ToString() { throw null; } } public partial class NavigationException : System.Exception { public NavigationException(string uri) { } - public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class NavigationManager { @@ -288,7 +293,7 @@ namespace Microsoft.AspNetCore.Components public abstract partial class OwningComponentBase : Microsoft.AspNetCore.Components.ComponentBase, System.IDisposable { protected OwningComponentBase() { } - protected bool IsDisposed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected bool IsDisposed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected System.IServiceProvider ScopedServices { get { throw null; } } protected virtual void Dispose(bool disposing) { } void System.IDisposable.Dispose() { } @@ -302,16 +307,16 @@ namespace Microsoft.AspNetCore.Components public sealed partial class ParameterAttribute : System.Attribute { public ParameterAttribute() { } - public bool CaptureUnmatchedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool CaptureUnmatchedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ParameterValue { private readonly object _dummy; private readonly int _dummyPrimitive; - public bool Cascading { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool Cascading { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ParameterView @@ -350,21 +355,21 @@ namespace Microsoft.AspNetCore.Components public sealed partial class RouteAttribute : System.Attribute { public RouteAttribute(string template) { } - public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class RouteData { public RouteData(System.Type pageType, System.Collections.Generic.IReadOnlyDictionary routeValues) { } - public System.Type PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class RouteView : Microsoft.AspNetCore.Components.IComponent { public RouteView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Type DefaultLayout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type DefaultLayout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } protected virtual void Render(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } @@ -439,17 +444,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree public partial class EventFieldInfo { public EventFieldInfo() { } - public int ComponentId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object FieldValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int ComponentId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object FieldValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct RenderBatch { private readonly object _dummy; - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedComponentIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedEventHandlerIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange ReferenceFrames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange UpdatedComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + private readonly int _dummyPrimitive; + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedComponentIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedEventHandlerIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange ReferenceFrames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange UpdatedComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class Renderer : System.IDisposable { @@ -528,20 +534,20 @@ namespace Microsoft.AspNetCore.Components.Routing public partial class LocationChangedEventArgs : System.EventArgs { public LocationChangedEventArgs(string location, bool isNavigationIntercepted) { } - public bool IsNavigationIntercepted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsNavigationIntercepted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class Router : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, System.IDisposable { public Router() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Collections.Generic.IEnumerable AdditionalAssemblies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IEnumerable AdditionalAssemblies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Reflection.Assembly AppAssembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.Assembly AppAssembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Found { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Found { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment NotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment NotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } public void Dispose() { } System.Threading.Tasks.Task Microsoft.AspNetCore.Components.IHandleAfterRender.OnAfterRenderAsync() { throw null; } diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs index c4a48435b4..10a26b70af 100644 --- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs +++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs @@ -54,35 +54,35 @@ namespace Microsoft.AspNetCore.Components public sealed partial class BindElementAttribute : System.Attribute { public BindElementAttribute(string element, string suffix, string valueAttribute, string changeAttribute) { } - public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Element { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Element { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public sealed partial class CascadingParameterAttribute : System.Attribute { public CascadingParameterAttribute() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CascadingValue : Microsoft.AspNetCore.Components.IComponent { public CascadingValue() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public bool IsFixed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool IsFixed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } } public partial class ChangeEventArgs : System.EventArgs { public ChangeEventArgs() { } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class ComponentBase : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, Microsoft.AspNetCore.Components.IHandleEvent { @@ -119,13 +119,15 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct ElementReference { private readonly object _dummy; + private readonly int _dummyPrimitive; public ElementReference(string id) { throw null; } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct EventCallback { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Components.EventCallback Empty; public static readonly Microsoft.AspNetCore.Components.EventCallbackFactory Factory; public EventCallback(Microsoft.AspNetCore.Components.IHandleEvent receiver, System.MulticastDelegate @delegate) { throw null; } @@ -190,6 +192,7 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct EventCallbackWorkItem { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Components.EventCallbackWorkItem Empty; public EventCallbackWorkItem(System.MulticastDelegate @delegate) { throw null; } public System.Threading.Tasks.Task InvokeAsync(object arg) { throw null; } @@ -198,6 +201,7 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct EventCallback { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Components.EventCallback Empty; public EventCallback(Microsoft.AspNetCore.Components.IHandleEvent receiver, System.MulticastDelegate @delegate) { throw null; } public bool HasDelegate { get { throw null; } } @@ -208,10 +212,10 @@ namespace Microsoft.AspNetCore.Components { public EventHandlerAttribute(string attributeName, System.Type eventArgsType) { } public EventHandlerAttribute(string attributeName, System.Type eventArgsType, bool enableStopPropagation, bool enablePreventDefault) { } - public string AttributeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnablePreventDefault { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnableStopPropagation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AttributeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnablePreventDefault { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnableStopPropagation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IComponent { @@ -235,21 +239,21 @@ namespace Microsoft.AspNetCore.Components public sealed partial class LayoutAttribute : System.Attribute { public LayoutAttribute(System.Type layoutType) { } - public System.Type LayoutType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type LayoutType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class LayoutComponentBase : Microsoft.AspNetCore.Components.ComponentBase { protected LayoutComponentBase() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class LayoutView : Microsoft.AspNetCore.Components.IComponent { public LayoutView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Type Layout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type Layout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } } @@ -261,15 +265,16 @@ namespace Microsoft.AspNetCore.Components public readonly partial struct MarkupString { private readonly object _dummy; + private readonly int _dummyPrimitive; public MarkupString(string value) { throw null; } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static explicit operator Microsoft.AspNetCore.Components.MarkupString (string value) { throw null; } public override string ToString() { throw null; } } public partial class NavigationException : System.Exception { public NavigationException(string uri) { } - public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class NavigationManager { @@ -288,7 +293,7 @@ namespace Microsoft.AspNetCore.Components public abstract partial class OwningComponentBase : Microsoft.AspNetCore.Components.ComponentBase, System.IDisposable { protected OwningComponentBase() { } - protected bool IsDisposed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected bool IsDisposed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected System.IServiceProvider ScopedServices { get { throw null; } } protected virtual void Dispose(bool disposing) { } void System.IDisposable.Dispose() { } @@ -302,16 +307,16 @@ namespace Microsoft.AspNetCore.Components public sealed partial class ParameterAttribute : System.Attribute { public ParameterAttribute() { } - public bool CaptureUnmatchedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool CaptureUnmatchedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ParameterValue { private readonly object _dummy; private readonly int _dummyPrimitive; - public bool Cascading { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool Cascading { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ParameterView @@ -350,21 +355,21 @@ namespace Microsoft.AspNetCore.Components public sealed partial class RouteAttribute : System.Attribute { public RouteAttribute(string template) { } - public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class RouteData { public RouteData(System.Type pageType, System.Collections.Generic.IReadOnlyDictionary routeValues) { } - public System.Type PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class RouteView : Microsoft.AspNetCore.Components.IComponent { public RouteView() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Type DefaultLayout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type DefaultLayout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } protected virtual void Render(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } @@ -439,17 +444,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree public partial class EventFieldInfo { public EventFieldInfo() { } - public int ComponentId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object FieldValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int ComponentId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object FieldValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct RenderBatch { private readonly object _dummy; - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedComponentIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedEventHandlerIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange ReferenceFrames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Components.RenderTree.ArrayRange UpdatedComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + private readonly int _dummyPrimitive; + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedComponentIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange DisposedEventHandlerIDs { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange ReferenceFrames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Components.RenderTree.ArrayRange UpdatedComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class Renderer : System.IDisposable { @@ -528,20 +534,20 @@ namespace Microsoft.AspNetCore.Components.Routing public partial class LocationChangedEventArgs : System.EventArgs { public LocationChangedEventArgs(string location, bool isNavigationIntercepted) { } - public bool IsNavigationIntercepted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsNavigationIntercepted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class Router : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, System.IDisposable { public Router() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Collections.Generic.IEnumerable AdditionalAssemblies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IEnumerable AdditionalAssemblies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Reflection.Assembly AppAssembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.Assembly AppAssembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment Found { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment Found { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment NotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment NotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Attach(Microsoft.AspNetCore.Components.RenderHandle renderHandle) { } public void Dispose() { } System.Threading.Tasks.Task Microsoft.AspNetCore.Components.IHandleAfterRender.OnAfterRenderAsync() { throw null; } diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index f77689bde2..30ded5fe73 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -430,7 +430,7 @@ namespace Microsoft.AspNetCore.Components private static string FormatEnumValueCore(T value, CultureInfo culture) where T : struct, Enum { - return value.ToString(); // The overload that acccepts a culture is [Obsolete] + return value.ToString(); // The overload that accepts a culture is [Obsolete] } private static string FormatNullableEnumValueCore(T? value, CultureInfo culture) where T : struct, Enum @@ -440,7 +440,7 @@ namespace Microsoft.AspNetCore.Components return null; } - return value.Value.ToString(); // The overload that acccepts a culture is [Obsolete] + return value.Value.ToString(); // The overload that accepts a culture is [Obsolete] } /// @@ -1166,99 +1166,99 @@ namespace Microsoft.AspNetCore.Components public static BindFormatter Get() { - if (!_cache.TryGetValue(typeof(T), out var formattter)) + if (!_cache.TryGetValue(typeof(T), out var formatter)) { // We need to replicate all of the primitive cases that we handle here so that they will behave the same way. // The result will be cached. if (typeof(T) == typeof(string)) { - formattter = (BindFormatter)FormatStringValueCore; + formatter = (BindFormatter)FormatStringValueCore; } else if (typeof(T) == typeof(bool)) { - formattter = (BindFormatter)FormatBoolValueCore; + formatter = (BindFormatter)FormatBoolValueCore; } else if (typeof(T) == typeof(bool?)) { - formattter = (BindFormatter)FormatNullableBoolValueCore; + formatter = (BindFormatter)FormatNullableBoolValueCore; } else if (typeof(T) == typeof(int)) { - formattter = (BindFormatter)FormatIntValueCore; + formatter = (BindFormatter)FormatIntValueCore; } else if (typeof(T) == typeof(int?)) { - formattter = (BindFormatter)FormatNullableIntValueCore; + formatter = (BindFormatter)FormatNullableIntValueCore; } else if (typeof(T) == typeof(long)) { - formattter = (BindFormatter)FormatLongValueCore; + formatter = (BindFormatter)FormatLongValueCore; } else if (typeof(T) == typeof(long?)) { - formattter = (BindFormatter)FormatNullableLongValueCore; + formatter = (BindFormatter)FormatNullableLongValueCore; } else if (typeof(T) == typeof(float)) { - formattter = (BindFormatter)FormatFloatValueCore; + formatter = (BindFormatter)FormatFloatValueCore; } else if (typeof(T) == typeof(float?)) { - formattter = (BindFormatter)FormatNullableFloatValueCore; + formatter = (BindFormatter)FormatNullableFloatValueCore; } else if (typeof(T) == typeof(double)) { - formattter = (BindFormatter)FormatDoubleValueCore; + formatter = (BindFormatter)FormatDoubleValueCore; } else if (typeof(T) == typeof(double?)) { - formattter = (BindFormatter)FormatNullableDoubleValueCore; + formatter = (BindFormatter)FormatNullableDoubleValueCore; } else if (typeof(T) == typeof(decimal)) { - formattter = (BindFormatter)FormatDecimalValueCore; + formatter = (BindFormatter)FormatDecimalValueCore; } else if (typeof(T) == typeof(decimal?)) { - formattter = (BindFormatter)FormatNullableDecimalValueCore; + formatter = (BindFormatter)FormatNullableDecimalValueCore; } else if (typeof(T) == typeof(DateTime)) { - formattter = (BindFormatter)FormatDateTimeValueCore; + formatter = (BindFormatter)FormatDateTimeValueCore; } else if (typeof(T) == typeof(DateTime?)) { - formattter = (BindFormatter)FormatNullableDateTimeValueCore; + formatter = (BindFormatter)FormatNullableDateTimeValueCore; } else if (typeof(T) == typeof(DateTimeOffset)) { - formattter = (BindFormatter)FormatDateTimeOffsetValueCore; + formatter = (BindFormatter)FormatDateTimeOffsetValueCore; } else if (typeof(T) == typeof(DateTimeOffset?)) { - formattter = (BindFormatter)FormatNullableDateTimeOffsetValueCore; + formatter = (BindFormatter)FormatNullableDateTimeOffsetValueCore; } else if (typeof(T).IsEnum) { // We have to deal invoke this dynamically to work around the type constraint on Enum.TryParse. var method = _formatEnumValue ??= typeof(BindConverter).GetMethod(nameof(FormatEnumValueCore), BindingFlags.NonPublic | BindingFlags.Static); - formattter = method.MakeGenericMethod(typeof(T)).CreateDelegate(typeof(BindFormatter), target: null); + formatter = method.MakeGenericMethod(typeof(T)).CreateDelegate(typeof(BindFormatter), target: null); } else if (Nullable.GetUnderlyingType(typeof(T)) is Type innerType && innerType.IsEnum) { // We have to deal invoke this dynamically to work around the type constraint on Enum.TryParse. var method = _formatNullableEnumValue ??= typeof(BindConverter).GetMethod(nameof(FormatNullableEnumValueCore), BindingFlags.NonPublic | BindingFlags.Static); - formattter = method.MakeGenericMethod(innerType).CreateDelegate(typeof(BindFormatter), target: null); + formatter = method.MakeGenericMethod(innerType).CreateDelegate(typeof(BindFormatter), target: null); } else { - formattter = MakeTypeConverterFormatter(); + formatter = MakeTypeConverterFormatter(); } - _cache.TryAdd(typeof(T), formattter); + _cache.TryAdd(typeof(T), formatter); } - return (BindFormatter)formattter; + return (BindFormatter)formatter; } private static BindFormatter MakeTypeConverterFormatter() diff --git a/src/Components/Components/src/BindElementAttribute.cs b/src/Components/Components/src/BindElementAttribute.cs index ffc17a6049..4907b3e27e 100644 --- a/src/Components/Components/src/BindElementAttribute.cs +++ b/src/Components/Components/src/BindElementAttribute.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Components /// Constructs an instance of . /// /// The tag name of the element. - /// The suffix value. For example, set this to value for bind-value, or set this to null for bind. + /// The suffix value. For example, set this to value for bind-value, or set this to for bind. /// The name of the value attribute to be bound. /// The name of an attribute that will register an associated change event. public BindElementAttribute(string element, string suffix, string valueAttribute, string changeAttribute) @@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Components /// /// Gets the suffix value. - /// For example, this will be value to mean bind-value, or null to mean bind. + /// For example, this will be value to mean bind-value, or to mean bind. /// public string Suffix { get; } diff --git a/src/Components/Components/src/CascadingValue.cs b/src/Components/Components/src/CascadingValue.cs index db03b3d416..605d24134d 100644 --- a/src/Components/Components/src/CascadingValue.cs +++ b/src/Components/Components/src/CascadingValue.cs @@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Components _hasSetParametersPreviously = true; - // It's OK for the value to be null, but some "Value" param must be suppled + // It's OK for the value to be null, but some "Value" param must be supplied // because it serves no useful purpose to have a otherwise. if (!hasSuppliedValue) { diff --git a/src/Components/Components/src/ComponentBase.cs b/src/Components/Components/src/ComponentBase.cs index 51c95f386b..d4b38db345 100644 --- a/src/Components/Components/src/ComponentBase.cs +++ b/src/Components/Components/src/ComponentBase.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Components // about IComponent). This gives us flexibility to change the lifecycle concepts easily, // or for developers to design their own lifecycles as different base classes. - // TODO: When the component lifecycle design stabilises, add proper unit tests for ComponentBase. + // TODO: When the component lifecycle design stabilizes, add proper unit tests for ComponentBase. /// /// Optional base class for components. Alternatively, components may @@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Components /// /// /// The and lifecycle methods - /// are useful for performing interop, or interacting with values recieved from @ref. + /// are useful for performing interop, or interacting with values received from @ref. /// Use the parameter to ensure that initialization work is only performed /// once. /// @@ -156,7 +156,7 @@ namespace Microsoft.AspNetCore.Components /// A representing any asynchronous operation. /// /// The and lifecycle methods - /// are useful for performing interop, or interacting with values recieved from @ref. + /// are useful for performing interop, or interacting with values received from @ref. /// Use the parameter to ensure that initialization work is only performed /// once. /// @@ -246,7 +246,7 @@ namespace Microsoft.AspNetCore.Components } catch // avoiding exception filters for AOT runtime support { - // Ignore exceptions from task cancelletions. + // Ignore exceptions from task cancellations. // Awaiting a canceled task may produce either an OperationCanceledException (if produced as a consequence of // CancellationToken.ThrowIfCancellationRequested()) or a TaskCanceledException (produced as a consequence of awaiting Task.FromCanceled). // It's much easier to check the state of the Task (i.e. Task.IsCanceled) rather than catch two distinct exceptions. @@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Components } catch // avoiding exception filters for AOT runtime support { - // Ignore exceptions from task cancelletions, but don't bother issuing a state change. + // Ignore exceptions from task cancellations, but don't bother issuing a state change. if (task.IsCanceled) { return; diff --git a/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs b/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs index 99eac1965a..2a27533dfb 100644 --- a/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs +++ b/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs @@ -12,9 +12,9 @@ namespace Microsoft.AspNetCore.Components /// // // NOTE: for number parsing, the HTML5 spec dictates that the DOM will represent - // number values as floating point numbers using `.` as the period separator. This is NOT culture senstive. + // number values as floating point numbers using `.` as the period separator. This is NOT culture sensitive. // Put another way, the user might see `,` as their decimal separator, but the value available in events - // to JS code is always simpilar to what .NET parses with InvariantCulture. + // to JS code is always similar to what .NET parses with InvariantCulture. // // See: https://www.w3.org/TR/html5/sec-forms.html#number-state-typenumber // See: https://www.w3.org/TR/html5/infrastructure.html#valid-floating-point-number diff --git a/src/Components/Components/src/Microsoft.AspNetCore.Components.multitarget.nuspec b/src/Components/Components/src/Microsoft.AspNetCore.Components.multitarget.nuspec index 700ea95fa9..7017ce828e 100644 --- a/src/Components/Components/src/Microsoft.AspNetCore.Components.multitarget.nuspec +++ b/src/Components/Components/src/Microsoft.AspNetCore.Components.multitarget.nuspec @@ -9,7 +9,7 @@ - + diff --git a/src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp.nuspec b/src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp.nuspec index 8561bc2f2f..9ea33e53dc 100644 --- a/src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp.nuspec +++ b/src/Components/Components/src/Microsoft.AspNetCore.Components.netcoreapp.nuspec @@ -3,7 +3,7 @@ $CommonMetadataElements$ - + diff --git a/src/Components/Components/src/NavigationManager.cs b/src/Components/Components/src/NavigationManager.cs index d75077026f..0ad565fb54 100644 --- a/src/Components/Components/src/NavigationManager.cs +++ b/src/Components/Components/src/NavigationManager.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Components.Routing; namespace Microsoft.AspNetCore.Components { /// - /// Provides an abstraction for querying and mananging URI navigation. + /// Provides an abstraction for querying and managing URI navigation. /// public abstract class NavigationManager { @@ -134,7 +134,7 @@ namespace Microsoft.AspNetCore.Components } /// - /// Allows derived classes to lazyly self-initialize. Implementations that support lazy-initialization should override + /// Allows derived classes to lazily self-initialize. Implementations that support lazy-initialization should override /// this method and call . /// protected virtual void EnsureInitialized() diff --git a/src/Components/Components/src/RenderTree/RenderTreeFrameType.cs b/src/Components/Components/src/RenderTree/RenderTreeFrameType.cs index e73119e038..1e6249c8d7 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeFrameType.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeFrameType.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree public enum RenderTreeFrameType: short { /// - /// Used only for unintialized frames. + /// Used only for uninitialized frames. /// None = 0, diff --git a/src/Components/Components/src/RenderTree/Renderer.cs b/src/Components/Components/src/RenderTree/Renderer.cs index 05cfb41abe..09470cebda 100644 --- a/src/Components/Components/src/RenderTree/Renderer.cs +++ b/src/Components/Components/src/RenderTree/Renderer.cs @@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree // remaining work. // During the synchronous rendering process we don't wait for the pending asynchronous // work to finish as it will simply trigger new renders that will be handled afterwards. - // During the asynchronous rendering process we want to wait up untill al components have + // During the asynchronous rendering process we want to wait up until all components have // finished rendering so that we can produce the complete output. var componentState = GetRequiredComponentState(componentId); componentState.SetDirectParameters(initialParameters); @@ -388,7 +388,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree : null; /// - /// Processses pending renders requests from components if there are any. + /// Processes pending renders requests from components if there are any. /// protected virtual void ProcessPendingRender() { diff --git a/src/Components/Components/src/Rendering/RenderTreeBuilder.cs b/src/Components/Components/src/Rendering/RenderTreeBuilder.cs index f8a28273e4..3cc4aed9bf 100644 --- a/src/Components/Components/src/Rendering/RenderTreeBuilder.cs +++ b/src/Components/Components/src/Rendering/RenderTreeBuilder.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Components.Rendering // IMPORTANT // // Many of these names are used in code generation. Keep these in sync with the code generation code - // See: aspnet/AspNetCore-Tooling + // See: dotnet/aspnetcore-tooling /// /// Provides methods for building a collection of entries. @@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Components.Rendering AssertCanAddAttribute(); if (_lastNonAttributeFrameType == RenderTreeFrameType.Component) { - // Since this is a component, we need to preserve the type of the EventCallabck, so we have + // Since this is a component, we need to preserve the type of the EventCallback, so we have // to box. Append(RenderTreeFrame.Attribute(sequence, name, (object)value)); } diff --git a/src/Components/Components/src/Rendering/RendererSynchronizationContext.cs b/src/Components/Components/src/Rendering/RendererSynchronizationContext.cs index 176e4d83e4..d25d50b6de 100644 --- a/src/Components/Components/src/Rendering/RendererSynchronizationContext.cs +++ b/src/Components/Components/src/Rendering/RendererSynchronizationContext.cs @@ -147,20 +147,20 @@ namespace Microsoft.AspNetCore.Components.Rendering // synchronously runs the callback public override void Send(SendOrPostCallback d, object state) { - Task antecedant; + Task antecedent; var completion = new TaskCompletionSource(); lock (_state.Lock) { - antecedant = _state.Task; + antecedent = _state.Task; _state.Task = completion.Task; } // We have to block. That's the contract of Send - we don't expect this to be used // in many scenarios in Components. // - // Using Wait here is ok because the antecedant task will never throw. - antecedant.Wait(); + // Using Wait here is ok because the antecedent task will never throw. + antecedent.Wait(); ExecuteSynchronously(completion, d, state); } @@ -195,7 +195,7 @@ namespace Microsoft.AspNetCore.Components.Rendering ExecuteSynchronously(completion, d, state); } - private Task Enqueue(Task antecedant, SendOrPostCallback d, object state, bool forceAsync = false) + private Task Enqueue(Task antecedent, SendOrPostCallback d, object state, bool forceAsync = false) { // If we get here is means that a callback is being explicitly queued. Let's instead add it to the queue and yield. // @@ -212,7 +212,7 @@ namespace Microsoft.AspNetCore.Components.Rendering } var flags = forceAsync ? TaskContinuationOptions.RunContinuationsAsynchronously : TaskContinuationOptions.None; - return antecedant.ContinueWith(BackgroundWorkThunk, new WorkItem() + return antecedent.ContinueWith(BackgroundWorkThunk, new WorkItem() { SynchronizationContext = this, ExecutionContext = executionContext, diff --git a/src/Components/Components/test/CascadingParameterTest.cs b/src/Components/Components/test/CascadingParameterTest.cs index a906664741..522d027d6a 100644 --- a/src/Components/Components/test/CascadingParameterTest.cs +++ b/src/Components/Components/test/CascadingParameterTest.cs @@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Components.Test // Act/Assert 2: Re-render the CascadingValue; observe nested component wasn't re-rendered providedValue = "Updated value"; - displayNestedComponent = false; // Remove the nested componet + displayNestedComponent = false; // Remove the nested component component.TriggerRender(); // Assert: We did not render the nested component now it's been removed diff --git a/src/Components/Components/test/ParameterViewTest.Assignment.cs b/src/Components/Components/test/ParameterViewTest.Assignment.cs index 9df9feab9f..7dd8537f4c 100644 --- a/src/Components/Components/test/ParameterViewTest.Assignment.cs +++ b/src/Components/Components/test/ParameterViewTest.Assignment.cs @@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Components [Fact] public void IncomingParameterMatchesOverridenParameter_ThatDoesNotHasAttribute() { - // Test for https://github.com/aspnet/AspNetCore/issues/13162 + // Test for https://github.com/dotnet/aspnetcore/issues/13162 // Arrange var parameters = new ParameterViewBuilder { @@ -366,7 +366,7 @@ namespace Microsoft.AspNetCore.Components public void HasDuplicateCaptureUnmatchedValuesParameters_Throws() { // Arrange - var target = new HasDupliateCaptureUnmatchedValuesProperty(); + var target = new HasDuplicateCaptureUnmatchedValuesProperty(); var parameters = new ParameterViewBuilder().Build(); // Act @@ -374,17 +374,17 @@ namespace Microsoft.AspNetCore.Components // Assert Assert.Equal( - $"Multiple properties were found on component type '{typeof(HasDupliateCaptureUnmatchedValuesProperty).FullName}' " + + $"Multiple properties were found on component type '{typeof(HasDuplicateCaptureUnmatchedValuesProperty).FullName}' " + $"with '{nameof(ParameterAttribute)}.{nameof(ParameterAttribute.CaptureUnmatchedValues)}'. " + $"Only a single property per type can use '{nameof(ParameterAttribute)}.{nameof(ParameterAttribute.CaptureUnmatchedValues)}'. " + $"Properties:" + Environment.NewLine + - $"{nameof(HasDupliateCaptureUnmatchedValuesProperty.CaptureUnmatchedValuesProp1)}" + Environment.NewLine + - $"{nameof(HasDupliateCaptureUnmatchedValuesProperty.CaptureUnmatchedValuesProp2)}", + $"{nameof(HasDuplicateCaptureUnmatchedValuesProperty.CaptureUnmatchedValuesProp1)}" + Environment.NewLine + + $"{nameof(HasDuplicateCaptureUnmatchedValuesProperty.CaptureUnmatchedValuesProp2)}", ex.Message); } [Fact] - public void HasCaptureUnmatchedValuesParameteterWithWrongType_Throws() + public void HasCaptureUnmatchedValuesParameterWithWrongType_Throws() { // Arrange var target = new HasWrongTypeCaptureUnmatchedValuesProperty(); @@ -630,7 +630,7 @@ namespace Microsoft.AspNetCore.Components [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary CaptureUnmatchedValues { get; set; } } - class HasDupliateCaptureUnmatchedValuesProperty + class HasDuplicateCaptureUnmatchedValuesProperty { [Parameter(CaptureUnmatchedValues = true)] public Dictionary CaptureUnmatchedValuesProp1 { get; set; } [Parameter(CaptureUnmatchedValues = true)] public IDictionary CaptureUnmatchedValuesProp2 { get; set; } diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index 28f617eba2..9f3ba71809 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -442,7 +442,7 @@ namespace Microsoft.AspNetCore.Components.Test [Fact] public void HandlesKeyBeingAdded() { - // This is an anomolous situation that can't occur with .razor components. + // This is an anomalous situation that can't occur with .razor components. // It represents the case where, for the same sequence number, we have an // old frame without a key and a new frame with a key. @@ -472,7 +472,7 @@ namespace Microsoft.AspNetCore.Components.Test [Fact] public void HandlesKeyBeingRemoved() { - // This is an anomolous situation that can't occur with .razor components. + // This is an anomalous situation that can't occur with .razor components. // It represents the case where, for the same sequence number, we have an // old frame with a key and a new frame without a key. diff --git a/src/Components/Components/test/RendererTest.cs b/src/Components/Components/test/RendererTest.cs index d0e2affea2..77e0b06faa 100644 --- a/src/Components/Components/test/RendererTest.cs +++ b/src/Components/Components/test/RendererTest.cs @@ -2575,7 +2575,7 @@ namespace Microsoft.AspNetCore.Components.Test [Fact] public async Task CanCombineBindAndConditionalAttribute() { - // This test represents https://github.com/aspnet/Blazor/issues/624 + // This test represents https://github.com/dotnet/blazor/issues/624 // Arrange: Rendered with textbox enabled var renderer = new TestRenderer(); @@ -2811,7 +2811,7 @@ namespace Microsoft.AspNetCore.Components.Test } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7487")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/7487")] public async Task CanTriggerEventHandlerDisposedInEarlierPendingBatchAsync() { // This represents the scenario where the same event handler is being triggered @@ -3574,7 +3574,7 @@ namespace Microsoft.AspNetCore.Components.Test // Act &A Assert renderer.Dispose(); - // All components must be disposed even if some throw as part of being diposed. + // All components must be disposed even if some throw as part of being disposed. Assert.True(component.Disposed); var aex = Assert.IsType(Assert.Single(renderer.HandledExceptions)); Assert.Contains(exception1, aex.InnerExceptions); diff --git a/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs b/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs index 31364dca00..b4ad71cba2 100644 --- a/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs +++ b/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs @@ -301,7 +301,7 @@ namespace Microsoft.AspNetCore.Components.Rendering [Fact] public void CanAddMultipleAttributes_WithChildRegion() { - // This represents bug https://github.com/aspnet/AspNetCore/issues/16570 + // This represents bug https://github.com/dotnet/aspnetcore/issues/16570 // If a sequence of attributes is terminated by a call to builder.OpenRegion, // then the attribute deduplication logic wasn't working correctly diff --git a/src/Components/Components/test/Rendering/RendererSynchronizationContextTest.cs b/src/Components/Components/test/Rendering/RendererSynchronizationContextTest.cs index 568d2501bb..c92a585bd6 100644 --- a/src/Components/Components/test/Rendering/RendererSynchronizationContextTest.cs +++ b/src/Components/Components/test/Rendering/RendererSynchronizationContextTest.cs @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Components.Rendering } [Fact] - public void Post_RunsAynchronously_WhenNotBusy_Exception() + public void Post_RunsAsynchronously_WhenNotBusy_Exception() { // Arrange var context = new RendererSynchronizationContext(); diff --git a/src/Components/Components/test/Routing/RouteTableFactoryTests.cs b/src/Components/Components/test/Routing/RouteTableFactoryTests.cs index 92bea90d79..e596f27956 100644 --- a/src/Components/Components/test/Routing/RouteTableFactoryTests.cs +++ b/src/Components/Components/test/Routing/RouteTableFactoryTests.cs @@ -369,7 +369,7 @@ namespace Microsoft.AspNetCore.Components.Test.Routing [Fact] public void DoesNotThrowIfStableSortComparesRouteWithItself() { - // Test for https://github.com/aspnet/AspNetCore/issues/13313 + // Test for https://github.com/dotnet/aspnetcore/issues/13313 // Arrange & Act var builder = new TestRouteTableBuilder(); builder.AddRoute("r16"); diff --git a/src/Components/Directory.Build.props b/src/Components/Directory.Build.props index ef310ac60d..b614476c4c 100644 --- a/src/Components/Directory.Build.props +++ b/src/Components/Directory.Build.props @@ -2,7 +2,7 @@ - + diff --git a/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netcoreapp.cs b/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netcoreapp.cs index 4674ff0fb4..c1961a8a25 100644 --- a/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netcoreapp.cs +++ b/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netcoreapp.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components.Forms public sealed partial class EditContext { public EditContext(object model) { } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public event System.EventHandler OnFieldChanged { add { } remove { } } public event System.EventHandler OnValidationRequested { add { } remove { } } public event System.EventHandler OnValidationStateChanged { add { } remove { } } @@ -35,15 +35,16 @@ namespace Microsoft.AspNetCore.Components.Forms public sealed partial class FieldChangedEventArgs : System.EventArgs { public FieldChangedEventArgs(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { } - public Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct FieldIdentifier : System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public FieldIdentifier(object model, string fieldName) { throw null; } - public string FieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Components.Forms.FieldIdentifier Create(System.Linq.Expressions.Expression> accessor) { throw null; } public bool Equals(Microsoft.AspNetCore.Components.Forms.FieldIdentifier otherIdentifier) { throw null; } public override bool Equals(object obj) { throw null; } diff --git a/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netstandard2.0.cs b/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netstandard2.0.cs index 4674ff0fb4..c1961a8a25 100644 --- a/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netstandard2.0.cs +++ b/src/Components/Forms/ref/Microsoft.AspNetCore.Components.Forms.netstandard2.0.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components.Forms public sealed partial class EditContext { public EditContext(object model) { } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public event System.EventHandler OnFieldChanged { add { } remove { } } public event System.EventHandler OnValidationRequested { add { } remove { } } public event System.EventHandler OnValidationStateChanged { add { } remove { } } @@ -35,15 +35,16 @@ namespace Microsoft.AspNetCore.Components.Forms public sealed partial class FieldChangedEventArgs : System.EventArgs { public FieldChangedEventArgs(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { } - public Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct FieldIdentifier : System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public FieldIdentifier(object model, string fieldName) { throw null; } - public string FieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Components.Forms.FieldIdentifier Create(System.Linq.Expressions.Expression> accessor) { throw null; } public bool Equals(Microsoft.AspNetCore.Components.Forms.FieldIdentifier otherIdentifier) { throw null; } public override bool Equals(object obj) { throw null; } diff --git a/src/Components/Forms/src/FieldIdentifier.cs b/src/Components/Forms/src/FieldIdentifier.cs index 1c2c923d38..41fe513a43 100644 --- a/src/Components/Forms/src/FieldIdentifier.cs +++ b/src/Components/Forms/src/FieldIdentifier.cs @@ -3,6 +3,7 @@ using System; using System.Linq.Expressions; +using System.Runtime.CompilerServices; namespace Microsoft.AspNetCore.Components.Forms { @@ -35,7 +36,7 @@ namespace Microsoft.AspNetCore.Components.Forms /// The name of the editable field. public FieldIdentifier(object model, string fieldName) { - if (model == null) + if (model is null) { throw new ArgumentNullException(nameof(model)); } @@ -64,7 +65,16 @@ namespace Microsoft.AspNetCore.Components.Forms /// public override int GetHashCode() - => (Model, FieldName).GetHashCode(); + { + // We want to compare Model instances by reference. RuntimeHelpers.GetHashCode returns identical hashes for equal object references (ignoring any `Equals`/`GetHashCode` overrides) which is what we want. + var modelHash = RuntimeHelpers.GetHashCode(Model); + var fieldHash = StringComparer.Ordinal.GetHashCode(FieldName); + return ( + modelHash, + fieldHash + ) + .GetHashCode(); + } /// public override bool Equals(object obj) @@ -75,7 +85,7 @@ namespace Microsoft.AspNetCore.Components.Forms public bool Equals(FieldIdentifier otherIdentifier) { return - otherIdentifier.Model == Model && + ReferenceEquals(otherIdentifier.Model, Model) && string.Equals(otherIdentifier.FieldName, FieldName, StringComparison.Ordinal); } diff --git a/src/Components/Forms/test/EditContextTest.cs b/src/Components/Forms/test/EditContextTest.cs index 5c8e7af36e..e26bda2c7f 100644 --- a/src/Components/Forms/test/EditContextTest.cs +++ b/src/Components/Forms/test/EditContextTest.cs @@ -236,5 +236,35 @@ namespace Microsoft.AspNetCore.Components.Forms Assert.False(isValid); Assert.Equal(new[] { "Some message" }, editContext.GetValidationMessages()); } + + [Fact] + public void LookingUpModel_ThatOverridesGetHashCodeAndEquals_Works() + { + // Test for https://github.com/aspnet/AspNetCore/issues/18069 + // Arrange + var model = new EquatableModel(); + var editContext = new EditContext(model); + + editContext.NotifyFieldChanged(editContext.Field(nameof(EquatableModel.Property))); + + model.Property = "new value"; + + Assert.True(editContext.IsModified(editContext.Field(nameof(EquatableModel.Property)))); + } + + class EquatableModel : IEquatable + { + public string Property { get; set; } = ""; + + public bool Equals(EquatableModel other) + { + return string.Equals(Property, other?.Property, StringComparison.Ordinal); + } + + public override int GetHashCode() + { + return StringComparer.Ordinal.GetHashCode(Property); + } + } } } diff --git a/src/Components/Forms/test/FieldIdentifierTest.cs b/src/Components/Forms/test/FieldIdentifierTest.cs index f19751a45d..6192017b59 100644 --- a/src/Components/Forms/test/FieldIdentifierTest.cs +++ b/src/Components/Forms/test/FieldIdentifierTest.cs @@ -76,6 +76,19 @@ namespace Microsoft.AspNetCore.Components.Forms Assert.False(fieldIdentifier1.Equals(fieldIdentifier2)); } + [Fact] + public void FieldIdentifier_ForModelWithoutField_ProduceSameHashCodesAndEquality() + { + // Arrange + var model = new object(); + var fieldIdentifier1 = new FieldIdentifier(model, fieldName: string.Empty); + var fieldIdentifier2 = new FieldIdentifier(model, fieldName: string.Empty); + + // Act/Assert + Assert.Equal(fieldIdentifier1.GetHashCode(), fieldIdentifier2.GetHashCode()); + Assert.True(fieldIdentifier1.Equals(fieldIdentifier2)); + } + [Fact] public void SameContentsProduceSameHashCodesAndEquality() { @@ -89,6 +102,20 @@ namespace Microsoft.AspNetCore.Components.Forms Assert.True(fieldIdentifier1.Equals(fieldIdentifier2)); } + [Fact] + public void SameContents_WithOverridenEqualsAndGetHashCode_ProduceSameHashCodesAndEquality() + { + // Arrange + var model = new EquatableModel(); + var fieldIdentifier1 = new FieldIdentifier(model, nameof(EquatableModel.Property)); + model.Property = "changed value"; // To show it makes no difference if the overridden `GetHashCode` result changes + var fieldIdentifier2 = new FieldIdentifier(model, nameof(EquatableModel.Property)); + + // Act/Assert + Assert.Equal(fieldIdentifier1.GetHashCode(), fieldIdentifier2.GetHashCode()); + Assert.True(fieldIdentifier1.Equals(fieldIdentifier2)); + } + [Fact] public void FieldNamesAreCaseSensitive() { @@ -194,5 +221,20 @@ namespace Microsoft.AspNetCore.Components.Forms { public TestModel Child { get; set; } } + + class EquatableModel : IEquatable + { + public string Property { get; set; } = ""; + + public bool Equals(EquatableModel other) + { + return string.Equals(Property, other?.Property, StringComparison.Ordinal); + } + + public override int GetHashCode() + { + return StringComparer.Ordinal.GetHashCode(Property); + } + } } } diff --git a/src/Components/README.md b/src/Components/README.md index 6eacb16cda..f234cefc74 100644 --- a/src/Components/README.md +++ b/src/Components/README.md @@ -8,7 +8,7 @@ Blazor is a component based web UI framework. Blazor apps can run client-side in Blazor uses only the latest web standards. No plugins or transpilation needed. It runs in the browser on a real .NET runtime implemented in [WebAssembly](http://webassembly.org) that executes normal .NET assemblies. -[![Gitter](https://badges.gitter.im/aspnet/Blazor.svg)](https://gitter.im/aspnet/Blazor?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[![Gitter](https://badges.gitter.im/dotnet/blazor.svg)](https://gitter.im/dotnet/blazor?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) You can learn more about Blazor at https://blazor.net. diff --git a/src/Components/Server/ref/Microsoft.AspNetCore.Components.Server.netcoreapp.cs b/src/Components/Server/ref/Microsoft.AspNetCore.Components.Server.netcoreapp.cs index b9cfbda974..6265d868b9 100644 --- a/src/Components/Server/ref/Microsoft.AspNetCore.Components.Server.netcoreapp.cs +++ b/src/Components/Server/ref/Microsoft.AspNetCore.Components.Server.netcoreapp.cs @@ -21,11 +21,11 @@ namespace Microsoft.AspNetCore.Components.Server public sealed partial class CircuitOptions { public CircuitOptions() { } - public bool DetailedErrors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int DisconnectedCircuitMaxRetained { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan DisconnectedCircuitRetentionPeriod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan JSInteropDefaultCallTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MaxBufferedUnacknowledgedRenderBatches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool DetailedErrors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int DisconnectedCircuitMaxRetained { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan DisconnectedCircuitRetentionPeriod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan JSInteropDefaultCallTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MaxBufferedUnacknowledgedRenderBatches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class RevalidatingServerAuthenticationStateProvider : Microsoft.AspNetCore.Components.Server.ServerAuthenticationStateProvider, System.IDisposable { diff --git a/src/Components/Server/src/CircuitDisconnectMiddleware.cs b/src/Components/Server/src/CircuitDisconnectMiddleware.cs index d64c31e7da..03c8c551e3 100644 --- a/src/Components/Server/src/CircuitDisconnectMiddleware.cs +++ b/src/Components/Server/src/CircuitDisconnectMiddleware.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Components.Server { - // We use a middlware so that we can use DI. + // We use a middleware so that we can use DI. internal class CircuitDisconnectMiddleware { private const string CircuitIdKey = "circuitId"; @@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Components.Server LoggerMessage.Define(LogLevel.Debug, new EventId(2, "CircuitTerminatedGracefully"), "Circuit with id '{CircuitId}' terminated gracefully."); private static readonly Action _invalidCircuitId = - LoggerMessage.Define(LogLevel.Debug, new EventId(3, "InvalidCircuitId"), "CircuitDisconnectMiddleware recieved an invalid circuit id '{CircuitIdSecret}'."); + LoggerMessage.Define(LogLevel.Debug, new EventId(3, "InvalidCircuitId"), "CircuitDisconnectMiddleware received an invalid circuit id '{CircuitIdSecret}'."); public static void CircuitTerminatingGracefully(ILogger logger, CircuitId circuitId) => _circuitTerminatingGracefully(logger, circuitId, null); diff --git a/src/Components/Server/src/CircuitOptions.cs b/src/Components/Server/src/CircuitOptions.cs index 68ca25c85a..9f862b069d 100644 --- a/src/Components/Server/src/CircuitOptions.cs +++ b/src/Components/Server/src/CircuitOptions.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Components.Server /// without losing any state in the event of transient connection issues. /// /// - /// This value determines the maximium number of circuit states retained by the server. + /// This value determines the maximum number of circuit states retained by the server. /// /// /// @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Components.Server /// without losing any state in the event of transient connection issues. /// /// - /// This value determines the maximium duration circuit state is retained by the server before being evicted. + /// This value determines the maximum duration circuit state is retained by the server before being evicted. /// /// /// diff --git a/src/Components/Server/src/Circuits/CircuitHost.cs b/src/Components/Server/src/Circuits/CircuitHost.cs index 47a04da3a9..0c43ce2699 100644 --- a/src/Components/Server/src/Circuits/CircuitHost.cs +++ b/src/Components/Server/src/Circuits/CircuitHost.cs @@ -356,7 +356,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits // EndInvokeJSFromDotNet is used in a fire-and-forget context, so it's responsible for its own // error handling. - public async Task EndInvokeJSFromDotNet(long asyncCall, bool succeded, string arguments) + public async Task EndInvokeJSFromDotNet(long asyncCall, bool succeeded, string arguments) { AssertInitialized(); AssertNotDisposed(); @@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits { await Renderer.Dispatcher.InvokeAsync(() => { - if (!succeded) + if (!succeeded) { // We can log the arguments here because it is simply the JS error with the call stack. Log.EndInvokeJSFailed(_logger, asyncCall, arguments); @@ -578,11 +578,11 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits private static class Log { - private static readonly Action _intializationStarted; - private static readonly Action _intializationSucceded; - private static readonly Action _intializationFailed; + private static readonly Action _initializationStarted; + private static readonly Action _initializationSucceded; + private static readonly Action _initializationFailed; private static readonly Action _disposeStarted; - private static readonly Action _disposeSucceded; + private static readonly Action _disposeSucceeded; private static readonly Action _disposeFailed; private static readonly Action _onCircuitOpened; private static readonly Action _onConnectionUp; @@ -640,7 +640,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits public static readonly EventId EndInvokeJSSucceeded = new EventId(206, "EndInvokeJSSucceeded"); public static readonly EventId DispatchEventThroughJSInterop = new EventId(207, "DispatchEventThroughJSInterop"); public static readonly EventId LocationChange = new EventId(208, "LocationChange"); - public static readonly EventId LocationChangeSucceded = new EventId(209, "LocationChangeSucceeded"); + public static readonly EventId LocationChangeSucceeded = new EventId(209, "LocationChangeSucceeded"); public static readonly EventId LocationChangeFailed = new EventId(210, "LocationChangeFailed"); public static readonly EventId LocationChangeFailedInCircuit = new EventId(211, "LocationChangeFailedInCircuit"); public static readonly EventId OnRenderCompletedFailed = new EventId(212, "OnRenderCompletedFailed"); @@ -648,17 +648,17 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits static Log() { - _intializationStarted = LoggerMessage.Define( + _initializationStarted = LoggerMessage.Define( LogLevel.Debug, EventIds.InitializationStarted, "Circuit initialization started."); - _intializationSucceded = LoggerMessage.Define( + _initializationSucceded = LoggerMessage.Define( LogLevel.Debug, EventIds.InitializationSucceeded, "Circuit initialization succeeded."); - _intializationFailed = LoggerMessage.Define( + _initializationFailed = LoggerMessage.Define( LogLevel.Debug, EventIds.InitializationFailed, "Circuit initialization failed."); @@ -668,10 +668,10 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits EventIds.DisposeStarted, "Disposing circuit '{CircuitId}' started."); - _disposeSucceded = LoggerMessage.Define( + _disposeSucceeded = LoggerMessage.Define( LogLevel.Debug, EventIds.DisposeSucceeded, - "Disposing circuit '{CircuitId}' succeded."); + "Disposing circuit '{CircuitId}' succeeded."); _disposeFailed = LoggerMessage.Define( LogLevel.Debug, @@ -726,7 +726,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits _unhandledExceptionClientDisconnected = LoggerMessage.Define( LogLevel.Debug, EventIds.UnhandledExceptionClientDisconnected, - "An exception ocurred on the circuit host '{CircuitId}' while the client is disconnected."); + "An exception occurred on the circuit host '{CircuitId}' while the client is disconnected."); _beginInvokeDotNetStatic = LoggerMessage.Define( LogLevel.Debug, @@ -780,8 +780,8 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits _locationChangeSucceeded = LoggerMessage.Define( LogLevel.Debug, - EventIds.LocationChangeSucceded, - "Location change to '{URI}' in circuit '{CircuitId}' succeded."); + EventIds.LocationChangeSucceeded, + "Location change to '{URI}' in circuit '{CircuitId}' succeeded."); _locationChangeFailed = LoggerMessage.Define( LogLevel.Debug, @@ -799,11 +799,11 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits "Failed to complete render batch '{RenderId}' in circuit host '{CircuitId}'."); } - public static void InitializationStarted(ILogger logger) => _intializationStarted(logger, null); - public static void InitializationSucceeded(ILogger logger) => _intializationSucceded(logger, null); - public static void InitializationFailed(ILogger logger, Exception exception) => _intializationFailed(logger, exception); + public static void InitializationStarted(ILogger logger) => _initializationStarted(logger, null); + public static void InitializationSucceeded(ILogger logger) => _initializationSucceded(logger, null); + public static void InitializationFailed(ILogger logger, Exception exception) => _initializationFailed(logger, exception); public static void DisposeStarted(ILogger logger, CircuitId circuitId) => _disposeStarted(logger, circuitId, null); - public static void DisposeSucceeded(ILogger logger, CircuitId circuitId) => _disposeSucceded(logger, circuitId, null); + public static void DisposeSucceeded(ILogger logger, CircuitId circuitId) => _disposeSucceeded(logger, circuitId, null); public static void DisposeFailed(ILogger logger, CircuitId circuitId, Exception exception) => _disposeFailed(logger, circuitId, exception); public static void CircuitOpened(ILogger logger, CircuitId circuitId) => _onCircuitOpened(logger, circuitId, null); public static void ConnectionUp(ILogger logger, CircuitId circuitId, string connectionId) => _onConnectionUp(logger, circuitId, connectionId, null); diff --git a/src/Components/Server/src/Circuits/CircuitIdFactory.cs b/src/Components/Server/src/Circuits/CircuitIdFactory.cs index 544a1b791c..7250ee8116 100644 --- a/src/Components/Server/src/Circuits/CircuitIdFactory.cs +++ b/src/Components/Server/src/Circuits/CircuitIdFactory.cs @@ -20,7 +20,6 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits private const int SecretLength = 64; private const int IdLength = 32; - private readonly RandomNumberGenerator _generator = RandomNumberGenerator.Create(); private readonly IDataProtector _protector; public CircuitIdFactory(IDataProtectionProvider provider) @@ -35,7 +34,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits public CircuitId CreateCircuitId() { var buffer = new byte[SecretLength]; - _generator.GetBytes(buffer); + RandomNumberGenerator.Fill(buffer); var id = new byte[IdLength]; Array.Copy( diff --git a/src/Components/Server/src/Circuits/CircuitRegistry.cs b/src/Components/Server/src/Circuits/CircuitRegistry.cs index ab261a108b..f8e4971a64 100644 --- a/src/Components/Server/src/Circuits/CircuitRegistry.cs +++ b/src/Components/Server/src/Circuits/CircuitRegistry.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits /// the to use the new client instance that attempted to reconnect to the server. Removing the entry from /// should ensure we no longer have to concern ourselves with entry expiration. /// - /// Knowing when a client disconnected is not an exact science. There's a fair possiblity that a client may reconnect before the server realizes. + /// Knowing when a client disconnected is not an exact science. There's a fair possibility that a client may reconnect before the server realizes. /// Consequently, we have to account for reconnects and disconnects occuring simultaneously as well as appearing out of order. /// To manage this, we use a critical section to manage all state transitions. /// @@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits else { // DisconnectCore may fail to disconnect the circuit if it was previously marked inactive or - // has been transfered to a new connection. Do not invoke the circuit handlers in this instance. + // has been transferred to a new connection. Do not invoke the circuit handlers in this instance. // We have to do in this instance. return Task.CompletedTask; @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits { // Transition the host from disconnected to connected if it's available. In this critical section, we return // an existing host if it's currently considered connected or transition a disconnected host to connected. - // Transfering also wires up the client to the new set. + // Transferring also wires up the client to the new set. (circuitHost, previouslyConnected) = ConnectCore(circuitId, clientProxy, connectionId); if (circuitHost == null) @@ -428,7 +428,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits _connectingToDisconnectedCircuit = LoggerMessage.Define( LogLevel.Debug, EventIds.ConnectingToDisconnectedCircuit, - "Transfering disconnected circuit {CircuitId} to connection {ConnectionId}."); + "Transferring disconnected circuit {CircuitId} to connection {ConnectionId}."); _failedToReconnectToCircuit = LoggerMessage.Define( LogLevel.Debug, diff --git a/src/Components/Server/src/Circuits/RemoteRenderer.cs b/src/Components/Server/src/Circuits/RemoteRenderer.cs index 509944e17a..063fa77965 100644 --- a/src/Components/Server/src/Circuits/RemoteRenderer.cs +++ b/src/Components/Server/src/Circuits/RemoteRenderer.cs @@ -90,14 +90,14 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits // as we have a client that is not acknowledging render batches fast enough (something we consider needs // to be fast). // The result is something as follows: - // Lets imagine an extreme case where the server produces a new batch every milisecond. - // Lets say the client is able to ACK a batch every 100 miliseconds. + // Lets imagine an extreme case where the server produces a new batch every millisecond. + // Lets say the client is able to ACK a batch every 100 milliseconds. // When the app starts the client might see the sequence 0->(MaxUnacknowledgedRenderBatches-1) and then - // after 100 miliseconds it sees it jump to 1xx, then to 2xx where xx is something between {0..99} the + // after 100 milliseconds it sees it jump to 1xx, then to 2xx where xx is something between {0..99} the // reason for this is that the server slows down rendering new batches to as fast as the client can consume // them. // Similarly, if a client were to send events at a faster pace than the server can consume them, the server - // would still proces the events, but would not produce new renders until it gets an ack that frees up space + // would still process the events, but would not produce new renders until it gets an ack that frees up space // for a new render. // We should never see UnacknowledgedRenderBatches.Count > _options.MaxBufferedUnacknowledgedRenderBatches @@ -202,7 +202,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits { // Send the render batch to the client // If the "send" operation fails (synchronously or asynchronously) or the client - // gets disconected simply give up. This likely means that + // gets disconnected simply give up. This likely means that // the circuit went offline while sending the data, so simply wait until the // client reconnects back or the circuit gets evicted because it stayed // disconnected for too long. @@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits // from the client that it has received and successfully applied all batches up to that point). // If receive an ack for a previously acknowledged batch, its an error, as the messages are - // guranteed to be delivered in order, so a message for a render batch of 2 will never arrive + // guaranteed to be delivered in order, so a message for a render batch of 2 will never arrive // after a message for a render batch for 3. // If that were to be the case, it would just be enough to relax the checks here and simply skip // the message. @@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits if (lastBatchId < incomingBatchId) { - // This exception is due to a bad client input, so we mark it as such to prevent loging it as a warning and + // This exception is due to a bad client input, so we mark it as such to prevent logging it as a warning and // flooding the logs with warnings. throw new InvalidOperationException($"Received an acknowledgement for batch with id '{incomingBatchId}' when the last batch produced was '{lastBatchId}'."); } diff --git a/src/Components/Server/test/Circuits/CircuitIdFactoryTest.cs b/src/Components/Server/test/Circuits/CircuitIdFactoryTest.cs index 35bc454416..588eadfdd8 100644 --- a/src/Components/Server/test/Circuits/CircuitIdFactoryTest.cs +++ b/src/Components/Server/test/Circuits/CircuitIdFactoryTest.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits } [Fact] - public void CreateCircuitId_Generates_GeneratesDifferentIds_ForSuccesiveCalls() + public void CreateCircuitId_Generates_GeneratesDifferentIds_ForSuccessiveCalls() { // Arrange var factory = TestCircuitIdFactory.CreateTestFactory(); diff --git a/src/Components/Server/test/Circuits/RemoteRendererTest.cs b/src/Components/Server/test/Circuits/RemoteRendererTest.cs index e7cda62bb2..6befe0c65d 100644 --- a/src/Components/Server/test/Circuits/RemoteRendererTest.cs +++ b/src/Components/Server/test/Circuits/RemoteRendererTest.cs @@ -179,7 +179,7 @@ namespace Microsoft.AspNetCore.Components.Web.Rendering // Assert Assert.Equal(new long[] { 2, 3, 4 }, renderIds); - Assert.True(task.Wait(3000), "One or more render batches werent acknowledged"); + Assert.True(task.Wait(3000), "One or more render batches weren't acknowledged"); await task; } @@ -233,7 +233,7 @@ namespace Microsoft.AspNetCore.Components.Web.Rendering exceptions.Add(e); }; - // Receive the ack for the intial batch + // Receive the ack for the initial batch _ = renderer.OnRenderCompletedAsync(2, null); // Receive the ack for the second batch _ = renderer.OnRenderCompletedAsync(3, null); diff --git a/src/Components/Server/test/ComponentEndpointRouteBuilderExtensionsTest.cs b/src/Components/Server/test/ComponentEndpointRouteBuilderExtensionsTest.cs index e0a6d8ff44..03a651d7be 100644 --- a/src/Components/Server/test/ComponentEndpointRouteBuilderExtensionsTest.cs +++ b/src/Components/Server/test/ComponentEndpointRouteBuilderExtensionsTest.cs @@ -66,9 +66,9 @@ namespace Microsoft.AspNetCore.Components.Server.Tests services.AddServerSideBlazor(); services.AddSingleton(new ConfigurationBuilder().Build()); - var serviceProvder = services.BuildServiceProvider(); + var serviceProvider = services.BuildServiceProvider(); - return new ApplicationBuilder(serviceProvder); + return new ApplicationBuilder(serviceProvider); } private class MyComponent : IComponent diff --git a/src/Components/Shared/src/ElementReferenceJsonConverter.cs b/src/Components/Shared/src/ElementReferenceJsonConverter.cs index 465a688bf2..80a7738107 100644 --- a/src/Components/Shared/src/ElementReferenceJsonConverter.cs +++ b/src/Components/Shared/src/ElementReferenceJsonConverter.cs @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Components } else { - throw new JsonException($"Unexcepted JSON Token {reader.TokenType}."); + throw new JsonException($"Unexpected JSON Token {reader.TokenType}."); } } @@ -49,4 +49,4 @@ namespace Microsoft.AspNetCore.Components writer.WriteEndObject(); } } -} \ No newline at end of file +} diff --git a/src/Components/Web.JS/Microsoft.AspNetCore.Components.Web.JS.npmproj b/src/Components/Web.JS/Microsoft.AspNetCore.Components.Web.JS.npmproj index 4e64a10edb..071e61a13a 100644 --- a/src/Components/Web.JS/Microsoft.AspNetCore.Components.Web.JS.npmproj +++ b/src/Components/Web.JS/Microsoft.AspNetCore.Components.Web.JS.npmproj @@ -6,6 +6,11 @@ false + + + + + 0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e,this.outputConsole=console}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:this.outputConsole.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:this.outputConsole.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:this.outputConsole.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:this.outputConsole.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=n(3),a=n(4),s=n(43),c=n(0),u=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),l=function(e){function t(t){var n=e.call(this)||this;return n.logger=t,n}return u(t,e),t.prototype.send=function(e){var t=this;return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new i.a):e.method?e.url?new Promise(function(n,r){var o=new XMLHttpRequest;o.open(e.method,e.url,!0),o.withCredentials=!0,o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.setRequestHeader("Content-Type","text/plain;charset=UTF-8");var s=e.headers;s&&Object.keys(s).forEach(function(e){o.setRequestHeader(e,s[e])}),e.responseType&&(o.responseType=e.responseType),e.abortSignal&&(e.abortSignal.onabort=function(){o.abort(),r(new i.a)}),e.timeout&&(o.timeout=e.timeout),o.onload=function(){e.abortSignal&&(e.abortSignal.onabort=null),o.status>=200&&o.status<300?n(new a.b(o.status,o.statusText,o.response||o.responseText)):r(new i.b(o.statusText,o.status))},o.onerror=function(){t.logger.log(c.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new i.b(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(c.a.Warning,"Timeout from HTTP request."),r(new i.c)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(a.a),f=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),h=function(e){function t(t){var n=e.call(this)||this;return"undefined"!=typeof XMLHttpRequest?n.httpClient=new l(t):n.httpClient=new s.a(t),n}return f(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new i.a):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(a.a),p=n(44);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(o||(o={}));var d,g=n(1),y=function(){function e(){this.observers=[]}return e.prototype.next=function(e){for(var t=0,n=this.observers;t0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?[2,Promise.reject(new Error("Unable to connect to the server with any of the available transports. "+i.join(" ")))]:[2,Promise.reject(new Error("None of the transports supported by the client are supported by the server."))]}})})},e.prototype.constructTransport=function(e){switch(e){case E.WebSockets:if(!this.options.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new A(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.WebSocket);case E.ServerSentEvents:if(!this.options.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new O(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.EventSource);case E.LongPolling:return new x(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1);default:throw new Error("Unknown transport: "+e+".")}},e.prototype.startTransport=function(e,t){var n=this;return this.transport.onreceive=this.onreceive,this.transport.onclose=function(e){return n.stopConnection(e)},this.transport.connect(e,t)},e.prototype.resolveTransportOrError=function(e,t,n){var r=E[e.transport];if(null==r)return this.logger.log(c.a.Debug,"Skipping transport '"+e.transport+"' because it is not supported by this client."),new Error("Skipping transport '"+e.transport+"' because it is not supported by this client.");if(!function(e,t){return!e||0!=(t&e)}(t,r))return this.logger.log(c.a.Debug,"Skipping transport '"+E[r]+"' because it was disabled by the client."),new Error("'"+E[r]+"' is disabled by the client.");if(!(e.transferFormats.map(function(e){return S[e]}).indexOf(n)>=0))return this.logger.log(c.a.Debug,"Skipping transport '"+E[r]+"' because it does not support the requested transfer format '"+S[n]+"'."),new Error("'"+E[r]+"' does not support "+S[n]+".");if(r===E.WebSockets&&!this.options.WebSocket||r===E.ServerSentEvents&&!this.options.EventSource)return this.logger.log(c.a.Debug,"Skipping transport '"+E[r]+"' because it is not supported in your environment.'"),new Error("'"+E[r]+"' is not supported in your environment.");this.logger.log(c.a.Debug,"Selecting transport '"+E[r]+"'.");try{return this.constructTransport(r)}catch(e){return e}},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.stopConnection=function(e){if(this.logger.log(c.a.Debug,"HttpConnection.stopConnection("+e+") called while in state "+this.connectionState+"."),this.transport=void 0,e=this.stopError||e,this.stopError=void 0,"Disconnected"!==this.connectionState)if("Connecting "!==this.connectionState){if("Disconnecting"===this.connectionState&&this.stopPromiseResolver(),e?this.logger.log(c.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(c.a.Information,"Connection disconnected."),this.connectionId=void 0,this.connectionState="Disconnected",this.onclose&&this.connectionStarted){this.connectionStarted=!1;try{this.onclose(e)}catch(t){this.logger.log(c.a.Error,"HttpConnection.onclose("+e+") threw error '"+t+"'.")}}}else this.logger.log(c.a.Warning,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection hasn't yet left the in the connecting state.");else this.logger.log(c.a.Debug,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is already in the disconnected state.")},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if(!g.c.isBrowser||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(c.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",-1===(n+=-1===t?"":e.substring(t)).indexOf("negotiateVersion")&&(n+=-1===t?"?":"&",n+="negotiateVersion="+this.negotiateVersion),n},e}();var q=function(){function e(e){this.transport=e,this.buffer=[],this.executing=!0,this.sendBufferedData=new W,this.transportResult=new W,this.sendLoopPromise=this.sendLoop()}return e.prototype.send=function(e){return this.bufferData(e),this.transportResult||(this.transportResult=new W),this.transportResult.promise},e.prototype.stop=function(){return this.executing=!1,this.sendBufferedData.resolve(),this.sendLoopPromise},e.prototype.bufferData=function(e){if(this.buffer.length&&typeof this.buffer[0]!=typeof e)throw new Error("Expected data to be of type "+typeof this.buffer+" but was of type "+typeof e);this.buffer.push(e),this.sendBufferedData.resolve()},e.prototype.sendLoop=function(){return B(this,void 0,void 0,function(){var t,n,r;return j(this,function(o){switch(o.label){case 0:return[4,this.sendBufferedData.promise];case 1:if(o.sent(),!this.executing)return this.transportResult&&this.transportResult.reject("Connection stopped."),[3,6];this.sendBufferedData=new W,t=this.transportResult,this.transportResult=void 0,n="string"==typeof this.buffer[0]?this.buffer.join(""):e.concatBuffers(this.buffer),this.buffer.length=0,o.label=2;case 2:return o.trys.push([2,4,,5]),[4,this.transport.send(n)];case 3:return o.sent(),t.resolve(),[3,5];case 4:return r=o.sent(),t.reject(r),[3,5];case 5:return[3,0];case 6:return[2]}})})},e.concatBuffers=function(e){for(var t=e.map(function(e){return e.byteLength}).reduce(function(e,t){return e+t}),n=new Uint8Array(t),r=0,o=0,i=e;o0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback&&this.subject.cancelCallback().catch(function(e){})},e}(),g=function(){function e(e){this.minimumLogLevel=e,this.outputConsole=console}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:this.outputConsole.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:this.outputConsole.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:this.outputConsole.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:this.outputConsole.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}();function y(){var e="X-SignalR-User-Agent";return u.isNode&&(e="User-Agent"),[e,v(s,b(),w(),m())]}function v(e,t,n,r){var o="Microsoft SignalR/",i=e.split(".");return o+=i[0]+"."+i[1],o+=" ("+e+"; ",o+=t&&""!==t?t+"; ":"Unknown OS; ",o+=""+n,o+=r?"; "+r:"; Unknown Runtime Version",o+=")"}function b(){if(!u.isNode)return"";switch(e.platform){case"win32":return"Windows NT";case"darwin":return"macOS";case"linux":return"Linux";default:return e.platform}}function m(){if(u.isNode)return e.versions.node}function w(){return u.isNode?"NodeJS":"Browser"}}).call(this,n(14))},function(e,t,n){"use strict";n.r(t);var r,o=n(3),i=n(4),a=n(0),s=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=200&&s.status<300?n(new i.b(s.status,s.statusText,s.response||s.responseText)):r(new o.b(s.statusText,s.status))},s.onerror=function(){t.logger.log(a.a.Warning,"Error from HTTP request. "+s.status+": "+s.statusText+"."),r(new o.b(s.statusText,s.status))},s.ontimeout=function(){t.logger.log(a.a.Warning,"Timeout from HTTP request."),r(new o.c)},s.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(i.a),y=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),v=function(e){function t(t){var n=e.call(this)||this;return"undefined"!=typeof fetch?n.httpClient=new f(t):"undefined"!=typeof XMLHttpRequest?n.httpClient=new g(t):n.httpClient=new p.a(t),n}return y(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new o.a):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(i.a),b=n(44);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(h||(h={}));var m,w=n(1),E=function(){function e(){this.observers=[]}return e.prototype.next=function(e){for(var t=0,n=this.observers;t0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?[2,Promise.reject(new Error("Unable to connect to the server with any of the available transports. "+i.join(" ")))]:[2,Promise.reject(new Error("None of the transports supported by the client are supported by the server."))]}})})},e.prototype.constructTransport=function(e){switch(e){case I.WebSockets:if(!this.options.WebSocket)throw new Error("'WebSocket' is not supported in your environment.");return new F(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.WebSocket);case I.ServerSentEvents:if(!this.options.EventSource)throw new Error("'EventSource' is not supported in your environment.");return new B(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.EventSource,this.options.withCredentials);case I.LongPolling:return new M(this.httpClient,this.accessTokenFactory,this.logger,this.options.logMessageContent||!1,this.options.withCredentials);default:throw new Error("Unknown transport: "+e+".")}},e.prototype.startTransport=function(e,t){var n=this;return this.transport.onreceive=this.onreceive,this.transport.onclose=function(e){return n.stopConnection(e)},this.transport.connect(e,t)},e.prototype.resolveTransportOrError=function(e,t,n){var r=I[e.transport];if(null==r)return this.logger.log(a.a.Debug,"Skipping transport '"+e.transport+"' because it is not supported by this client."),new Error("Skipping transport '"+e.transport+"' because it is not supported by this client.");if(!function(e,t){return!e||0!=(t&e)}(t,r))return this.logger.log(a.a.Debug,"Skipping transport '"+I[r]+"' because it was disabled by the client."),new Error("'"+I[r]+"' is disabled by the client.");if(!(e.transferFormats.map(function(e){return k[e]}).indexOf(n)>=0))return this.logger.log(a.a.Debug,"Skipping transport '"+I[r]+"' because it does not support the requested transfer format '"+k[n]+"'."),new Error("'"+I[r]+"' does not support "+k[n]+".");if(r===I.WebSockets&&!this.options.WebSocket||r===I.ServerSentEvents&&!this.options.EventSource)return this.logger.log(a.a.Debug,"Skipping transport '"+I[r]+"' because it is not supported in your environment.'"),new Error("'"+I[r]+"' is not supported in your environment.");this.logger.log(a.a.Debug,"Selecting transport '"+I[r]+"'.");try{return this.constructTransport(r)}catch(e){return e}},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.stopConnection=function(e){if(this.logger.log(a.a.Debug,"HttpConnection.stopConnection("+e+") called while in state "+this.connectionState+"."),this.transport=void 0,e=this.stopError||e,this.stopError=void 0,"Disconnected"!==this.connectionState){if("Connecting "===this.connectionState)throw this.logger.log(a.a.Warning,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is still in the connecting state."),new Error("HttpConnection.stopConnection("+e+") was called while the connection is still in the connecting state.");if("Disconnecting"===this.connectionState&&this.stopPromiseResolver(),e?this.logger.log(a.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(a.a.Information,"Connection disconnected."),this.connectionId=void 0,this.connectionState="Disconnected",this.onclose&&this.connectionStarted){this.connectionStarted=!1;try{this.onclose(e)}catch(t){this.logger.log(a.a.Error,"HttpConnection.onclose("+e+") threw error '"+t+"'.")}}}else this.logger.log(a.a.Debug,"Call to HttpConnection.stopConnection("+e+") was ignored because the connection is already in the disconnected state.")},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if(!w.c.isBrowser||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(a.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",-1===(n+=-1===t?"":e.substring(t)).indexOf("negotiateVersion")&&(n+=-1===t?"?":"&",n+="negotiateVersion="+this.negotiateVersion),n},e}();var K=function(){function e(e){this.transport=e,this.buffer=[],this.executing=!0,this.sendBufferedData=new V,this.transportResult=new V,this.sendLoopPromise=this.sendLoop()}return e.prototype.send=function(e){return this.bufferData(e),this.transportResult||(this.transportResult=new V),this.transportResult.promise},e.prototype.stop=function(){return this.executing=!1,this.sendBufferedData.resolve(),this.sendLoopPromise},e.prototype.bufferData=function(e){if(this.buffer.length&&typeof this.buffer[0]!=typeof e)throw new Error("Expected data to be of type "+typeof this.buffer+" but was of type "+typeof e);this.buffer.push(e),this.sendBufferedData.resolve()},e.prototype.sendLoop=function(){return H(this,void 0,void 0,function(){var t,n,r;return q(this,function(o){switch(o.label){case 0:return[4,this.sendBufferedData.promise];case 1:if(o.sent(),!this.executing)return this.transportResult&&this.transportResult.reject("Connection stopped."),[3,6];this.sendBufferedData=new V,t=this.transportResult,this.transportResult=void 0,n="string"==typeof this.buffer[0]?this.buffer.join(""):e.concatBuffers(this.buffer),this.buffer.length=0,o.label=2;case 2:return o.trys.push([2,4,,5]),[4,this.transport.send(n)];case 3:return o.sent(),t.resolve(),[3,5];case 4:return r=o.sent(),t.reject(r),[3,5];case 5:return[3,0];case 6:return[2]}})})},e.concatBuffers=function(e){for(var t=e.map(function(e){return e.byteLength}).reduce(function(e,t){return e+t}),n=new Uint8Array(t),r=0,o=0,i=e;o * @license MIT */ -var r=n(50),o=n(51),i=n(52);function a(){return c.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=c.from(t,r)),c.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,c=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,c/=2,n/=2}function u(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-c),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function _(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function I(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:u>223?3:u>191?2:1;if(o+f<=n)switch(f){case 1:u<128&&(l=u);break;case 2:128==(192&(i=e[o+1]))&&(c=(31&u)<<6|63&i)>127&&(l=c);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(c=(15&u)<<12|(63&i)<<6|63&a)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(c=(15&u)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&c<1114112&&(l=c)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=T)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return x(this,t,n);case"utf8":case"utf-8":return I(this,t,n);case"ascii":return k(this,t,n);case"latin1":case"binary":return P(this,t,n);case"base64":return _(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},c.prototype.equals=function(e){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===c.compare(this,e)},c.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},c.prototype.compare=function(e,t,n,r,o){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),u=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return m(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var T=4096;function k(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function O(e,t,n,r,o,i){if(!c.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function M(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function A(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function B(e,t,n,r,i){return i||A(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function j(e,t,n,r,i){return i||A(e,0,n,8),o.write(e,t,n,r,52,8),n+8}c.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},c.prototype.readUInt8=function(e,t){return t||D(e,1,this.length),this[e]},c.prototype.readUInt16LE=function(e,t){return t||D(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUInt16BE=function(e,t){return t||D(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUInt32LE=function(e,t){return t||D(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUInt32BE=function(e,t){return t||D(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||D(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},c.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||D(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},c.prototype.readInt8=function(e,t){return t||D(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){t||D(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt16BE=function(e,t){t||D(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt32LE=function(e,t){return t||D(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return t||D(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readFloatLE=function(e,t){return t||D(e,4,this.length),o.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return t||D(e,4,this.length),o.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return t||D(e,8,this.length),o.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return t||D(e,8,this.length),o.read(this,e,!1,52,8)},c.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||O(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},c.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,1,255,0),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},c.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},c.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},c.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):M(this,e,t,!0),t+4},c.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},c.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);O(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},c.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);O(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},c.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,1,127,-128),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},c.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},c.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):M(this,e,t,!0),t+4},c.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},c.prototype.writeFloatLE=function(e,t,n){return B(this,e,t,!0,n)},c.prototype.writeFloatBE=function(e,t,n){return B(this,e,t,!1,n)},c.prototype.writeDoubleLE=function(e,t,n){return j(this,e,t,!0,n)},c.prototype.writeDoubleBE=function(e,t,n){return j(this,e,t,!1,n)},c.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!c.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(U,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(9))},function(e,t,n){"use strict";n.d(t,"a",function(){return r});var r=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}()},function(e,t,n){"use strict";n.d(t,"a",function(){return r});var r=function(){function e(){}return e.write=function(t){return""+t+e.RecordSeparator},e.parse=function(t){if(t[t.length-1]!==e.RecordSeparator)throw new Error("Message is incomplete.");var n=t.split(e.RecordSeparator);return n.pop(),n},e.RecordSeparatorCode=30,e.RecordSeparator=String.fromCharCode(e.RecordSeparatorCode),e}()},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";var r=n(23),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(21);i.inherits=n(15);var a=n(36),s=n(41);i.inherits(f,a);for(var c=o(s.prototype),u=0;u=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(u(i)&&u(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(c(i))throw new Error("Not implemented: moving existing logical children");var a=u(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=c,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return u(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=u,t.permuteLogicalChildren=function(e,t){var n=u(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=c(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):h(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=l},function(e,t,n){var r=n(6),o=r.Buffer;function i(e,t){for(var n in e)t[n]=e[n]}function a(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=a),i(o,a),a.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},a.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Information=2]="Information",e[e.Warning=3]="Warning",e[e.Error=4]="Error",e[e.Critical=5]="Critical",e[e.None=6]="None"}(t.LogLevel||(t.LogLevel={}))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t,n,r){var o=u();if(o.invokeDotNetFromJS){var i=JSON.stringify(r,g),a=o.invokeDotNetFromJS(e,t,n,i);return a?f(a):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function c(e,t,r,i){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var a=o++,s=new Promise(function(e,t){n[a]={resolve:e,reject:t}});try{var c=JSON.stringify(i,g);u().beginInvokeDotNetFromJS(a,e,t,r,c)}catch(e){l(a,!1,e)}return s}function u(){if(null!==i)return i;throw new Error("No .NET call dispatcher has been set.")}function l(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function f(e){return e?JSON.parse(e,function(e,n){return t.reduce(function(t,n){return n(e,t)},n)}):null}function h(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach(function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e}),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){i=e},e.attachReviver=a,e.invokeMethod=function(e,t){for(var n=[],r=2;r1)for(var n=1;nthis.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,c=this._offset(n),u=r-n,l=u,f=s&&t||0,h=c[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){e=e||0,t=t||this.length,e<0&&(e+=this.length),t<0&&(t+=this.length);var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;e0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),c=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),b(r.showHidden)&&(r.showHidden=!1),b(r.depth)&&(r.depth=2),b(r.colors)&&(r.colors=!1),b(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=c),l(r,e,r.depth)}function c(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function u(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&C(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(b(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(C(n)){var c=n.name?": "+n.name:"";return e.stylize("[Function"+c+"]","special")}if(m(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var u,w="",_=!1,I=["{","}"];(p(n)&&(_=!0,I=["[","]"]),C(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return m(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||_&&0!=n.length?r<0?m(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),u=_?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(u,w,I)):I[0]+w+I[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,c;if((c=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),k(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(c.value)<0?(s=g(n)?l(e,c.value,null):l(e,c.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),b(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function b(e){return void 0===e}function m(e){return w(e)&&"[object RegExp]"===_(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===_(e)}function S(e){return w(e)&&("[object Error]"===_(e)||e instanceof Error)}function C(e){return"function"==typeof e}function _(e){return Object.prototype.toString.call(e)}function I(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(b(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=b,t.isRegExp=m,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=C,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(54);var T=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function k(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[I(e.getHours()),I(e.getMinutes()),I(e.getSeconds())].join(":"),[e.getDate(),T[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(55),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var P="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function x(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(P&&e[P]){var t;if("function"!=typeof(t=e[P]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,P,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===u.prototype||(t=function(e){return u.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):T(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function _(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(I,e):I(e))}function I(e){p("emit readable"),e.emit("readable"),R(e)}function T(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(k,e,t))}function k(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=u.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function O(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function M(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?O(this):_(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&O(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?D(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&O(this)),null!==r&&this.emit("data",r),r},m.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},m.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var c=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:m;function u(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",b),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",u),n.removeListener("end",l),n.removeListener("end",m),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(c):n.once("end",c),e.on("unpipe",u);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,R(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==M(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),m(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",b),m()}function b(){p("onfinish"),e.removeListener("close",v),m()}function m(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",b),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},m.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=a.length,s=c,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var c=o[e];if(void 0===c)return!1;if("function"==typeof c)i(c,this,t);else{var u=c.length,l=d(c,u);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(37).EventEmitter},function(e,t,n){"use strict";var r=n(23);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";var r=n(61).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=c,this.end=u,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function c(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function u(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";(function(t,r,o){var i=n(23);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=b;var s,c=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;b.WritableState=v;var u=n(21);u.inherits=n(15);var l={deprecate:n(64)},f=n(38),h=n(14).Buffer,p=o.Uint8Array||function(){};var d,g=n(39);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,u=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(u||0===u)?u:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(_,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),_(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?c(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function b(e){if(s=s||n(10),!(d.call(b,this)||this instanceof s))return new b(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function m(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),_(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,c=!0;n;)o[s]=n,n.isBuf||(c=!1),n=n.next,s+=1;o.allBuffers=c,m(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var u=n.chunk,l=n.encoding,f=n.callback;if(m(e,t,!1,t.objectMode?1:u.length,u,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function C(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),_(e,t)})}function _(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(C,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}u.inherits(b,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(b,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===b&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},b.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},b.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var c=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(b.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),b.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},b.prototype._writev=null,b.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,_(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(b.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),b.prototype.destroy=g.destroy,b.prototype._undestroy=g.undestroy,b.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(20),n(62).setImmediate,n(9))},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(21);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length=200&&c.statusCode<300?r(new a.b(c.statusCode,c.statusMessage||"",u)):o(new i.b(c.statusMessage||"",c.statusCode||0))});t.abortSignal&&(t.abortSignal.onabort=function(){f.abort(),o(new i.a)})})},n.prototype.getCookieString=function(e){return this.cookieJar.getCookieString(e)},n}(a.a)}).call(this,n(6).Buffer)},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return i});var r=n(8),o=n(1),i=function(){function t(){}return t.prototype.writeHandshakeRequest=function(e){return r.a.write(JSON.stringify(e))},t.prototype.parseHandshakeResponse=function(t){var n,i;if(Object(o.g)(t)||void 0!==e&&t instanceof e){var a=new Uint8Array(t);if(-1===(c=a.indexOf(r.a.RecordSeparatorCode)))throw new Error("Message is incomplete.");var s=c+1;n=String.fromCharCode.apply(null,a.slice(0,s)),i=a.byteLength>s?a.slice(s).buffer:null}else{var c,u=t;if(-1===(c=u.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=c+1;n=u.substring(0,s),i=u.length>s?u.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(6).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a},a=this&&this.__spread||function(){for(var e=[],t=0;t0?r-4:r,f=0;f>16&255,s[c++]=t>>8&255,s[c++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[c++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[c++]=t>>8&255,s[c++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,c=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,c=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-u;else{if(i===c)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=u}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,c,u=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-a))<1&&(a--,c*=2),(t+=a+f>=1?h/c:h*Math.pow(2,1-f))*c>=2&&(a++,c/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*c-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,u-=8);e[n+p-d]|=128*g}},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){"use strict";(function(t){ +var r=n(50),o=n(51),i=n(52);function a(){return c.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(c.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=c.from(t,r)),c.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,c=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,c/=2,n/=2}function u(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-c),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function _(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function T(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:u>223?3:u>191?2:1;if(o+f<=n)switch(f){case 1:u<128&&(l=u);break;case 2:128==(192&(i=e[o+1]))&&(c=(31&u)<<6|63&i)>127&&(l=c);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(c=(15&u)<<12|(63&i)<<6|63&a)>2047&&(c<55296||c>57343)&&(l=c);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(c=(15&u)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&c<1114112&&(l=c)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=I)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return P(this,t,n);case"utf8":case"utf-8":return T(this,t,n);case"ascii":return k(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return _(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},c.prototype.equals=function(e){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===c.compare(this,e)},c.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},c.prototype.compare=function(e,t,n,r,o){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),u=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return m(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var I=4096;function k(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function O(e,t,n,r,o,i){if(!c.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function M(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function A(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function j(e,t,n,r,i){return i||A(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function B(e,t,n,r,i){return i||A(e,0,n,8),o.write(e,t,n,r,52,8),n+8}c.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},c.prototype.readUInt8=function(e,t){return t||D(e,1,this.length),this[e]},c.prototype.readUInt16LE=function(e,t){return t||D(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUInt16BE=function(e,t){return t||D(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUInt32LE=function(e,t){return t||D(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUInt32BE=function(e,t){return t||D(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||D(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},c.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||D(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},c.prototype.readInt8=function(e,t){return t||D(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){t||D(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt16BE=function(e,t){t||D(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},c.prototype.readInt32LE=function(e,t){return t||D(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return t||D(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readFloatLE=function(e,t){return t||D(e,4,this.length),o.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return t||D(e,4,this.length),o.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return t||D(e,8,this.length),o.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return t||D(e,8,this.length),o.read(this,e,!1,52,8)},c.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||O(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},c.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,1,255,0),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},c.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},c.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},c.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):M(this,e,t,!0),t+4},c.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},c.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);O(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},c.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);O(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},c.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,1,127,-128),c.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},c.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},c.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):M(this,e,t,!0),t+4},c.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||O(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),c.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},c.prototype.writeFloatLE=function(e,t,n){return j(this,e,t,!0,n)},c.prototype.writeFloatBE=function(e,t,n){return j(this,e,t,!1,n)},c.prototype.writeDoubleLE=function(e,t,n){return B(this,e,t,!0,n)},c.prototype.writeDoubleBE=function(e,t,n){return B(this,e,t,!1,n)},c.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!c.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(U,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(9))},function(e,t,n){"use strict";n.d(t,"a",function(){return r});var r=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}()},function(e,t,n){"use strict";n.d(t,"a",function(){return r});var r=function(){function e(){}return e.write=function(t){return""+t+e.RecordSeparator},e.parse=function(t){if(t[t.length-1]!==e.RecordSeparator)throw new Error("Message is incomplete.");var n=t.split(e.RecordSeparator);return n.pop(),n},e.RecordSeparatorCode=30,e.RecordSeparator=String.fromCharCode(e.RecordSeparatorCode),e}()},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";var r=n(23),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(21);i.inherits=n(16);var a=n(36),s=n(41);i.inherits(f,a);for(var c=o(s.prototype),u=0;u=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function s(e,t,n){var i=e;if(e instanceof Comment&&(u(i)&&u(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(c(i))throw new Error("Not implemented: moving existing logical children");var a=u(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=c,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return u(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=u,t.permuteLogicalChildren=function(e,t){var n=u(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=c(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):h(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=l},function(e,t){var n,r,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function s(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var c,u=[],l=!1,f=-1;function h(){l&&c&&(l=!1,c.length?u=c.concat(u):f=-1,u.length&&p())}function p(){if(!l){var e=s(h);l=!0;for(var t=u.length;t;){for(c=u,u=[];++f1)for(var n=1;nthis.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,c=this._offset(n),u=r-n,l=u,f=s&&t||0,h=c[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){e=e||0,t=t||this.length,e<0&&(e+=this.length),t<0&&(t+=this.length);var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;e0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),c=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),b(r.showHidden)&&(r.showHidden=!1),b(r.depth)&&(r.depth=2),b(r.colors)&&(r.colors=!1),b(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=c),l(r,e,r.depth)}function c(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function u(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&C(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(b(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(C(n)){var c=n.name?": "+n.name:"";return e.stylize("[Function"+c+"]","special")}if(m(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var u,w="",_=!1,T=["{","}"];(p(n)&&(_=!0,T=["[","]"]),C(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return m(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||_&&0!=n.length?r<0?m(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),u=_?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(u,w,T)):T[0]+w+T[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,c;if((c=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=c.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):c.set&&(s=e.stylize("[Setter]","special")),k(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(c.value)<0?(s=g(n)?l(e,c.value,null):l(e,c.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),b(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function b(e){return void 0===e}function m(e){return w(e)&&"[object RegExp]"===_(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===_(e)}function S(e){return w(e)&&("[object Error]"===_(e)||e instanceof Error)}function C(e){return"function"==typeof e}function _(e){return Object.prototype.toString.call(e)}function T(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(b(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=b,t.isRegExp=m,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=C,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(54);var I=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function k(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[T(e.getHours()),T(e.getMinutes()),T(e.getSeconds())].join(":"),[e.getDate(),I[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(55),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function P(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===u.prototype||(t=function(e){return u.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):I(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function _(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(T,e):T(e))}function T(e){p("emit readable"),e.emit("readable"),R(e)}function I(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(k,e,t))}function k(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=u.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function O(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function M(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?O(this):_(this),null;if(0===(e=C(e,t))&&t.ended)return 0===t.length&&O(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?D(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&O(this)),null!==r&&this.emit("data",r),r},m.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},m.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var c=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:m;function u(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",b),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",u),n.removeListener("end",l),n.removeListener("end",m),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(c):n.once("end",c),e.on("unpipe",u);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,R(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==M(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),m(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",b),m()}function b(){p("onfinish"),e.removeListener("close",v),m()}function m(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",b),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},m.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=a.length,s=c,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var c=o[e];if(void 0===c)return!1;if("function"==typeof c)i(c,this,t);else{var u=c.length,l=d(c,u);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(37).EventEmitter},function(e,t,n){"use strict";var r=n(23);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";var r=n(61).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=c,this.end=u,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function c(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function u(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";(function(t,r,o){var i=n(23);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=b;var s,c=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;b.WritableState=v;var u=n(21);u.inherits=n(16);var l={deprecate:n(64)},f=n(38),h=n(15).Buffer,p=o.Uint8Array||function(){};var d,g=n(39);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,u=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(u||0===u)?u:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(_,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),_(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?c(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function b(e){if(s=s||n(10),!(d.call(b,this)||this instanceof s))return new b(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function m(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),_(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,c=!0;n;)o[s]=n,n.isBuf||(c=!1),n=n.next,s+=1;o.allBuffers=c,m(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var u=n.chunk,l=n.encoding,f=n.callback;if(m(e,t,!1,t.objectMode?1:u.length,u,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function C(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),_(e,t)})}function _(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(C,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}u.inherits(b,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(b,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===b&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},b.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},b.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var c=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(b.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),b.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},b.prototype._writev=null,b.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,_(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(b.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),b.prototype.destroy=g.destroy,b.prototype._undestroy=g.undestroy,b.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(62).setImmediate,n(9))},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(21);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length=200&&c.statusCode<300?r(new a.b(c.statusCode,c.statusMessage||"",u)):o(new i.b(c.statusMessage||"",c.statusCode||0))});t.abortSignal&&(t.abortSignal.onabort=function(){f.abort(),o(new i.a)})})},n.prototype.getCookieString=function(e){return this.cookieJar.getCookieString(e)},n}(a.a)}).call(this,n(6).Buffer)},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return i});var r=n(8),o=n(1),i=function(){function t(){}return t.prototype.writeHandshakeRequest=function(e){return r.a.write(JSON.stringify(e))},t.prototype.parseHandshakeResponse=function(t){var n,i;if(Object(o.i)(t)||void 0!==e&&t instanceof e){var a=new Uint8Array(t);if(-1===(c=a.indexOf(r.a.RecordSeparatorCode)))throw new Error("Message is incomplete.");var s=c+1;n=String.fromCharCode.apply(null,a.slice(0,s)),i=a.byteLength>s?a.slice(s).buffer:null}else{var c,u=t;if(-1===(c=u.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=c+1;n=u.substring(0,s),i=u.length>s?u.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(6).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a},a=this&&this.__spread||function(){for(var e=[],t=0;t0?r-4:r,f=0;f>16&255,s[c++]=t>>8&255,s[c++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[c++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[c++]=t>>8&255,s[c++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,c=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,c=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-u;else{if(i===c)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=u}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,c,u=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(c=Math.pow(2,-a))<1&&(a--,c*=2),(t+=a+f>=1?h/c:h*Math.pow(2,1-f))*c>=2&&(a++,c/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*c-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,u-=8);e[n+p-d]|=128*g}},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){"use strict";(function(t){ /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT */ -function r(e,t){if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);o=0;u--)if(l[u]!==f[u])return!1;for(u=l.length-1;u>=0;u--)if(c=l[u],!b(e[c],t[c],n,r))return!1;return!0}(e,t,n,a))}return n?e===t:e==t}function m(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function w(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function E(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&y(o,n,"Missing expected exception"+r);var a="string"==typeof r,s=!e&&o&&!n;if((!e&&i.isError(o)&&a&&w(o,n)||s)&&y(o,n,"Got unwanted exception"+r),e&&o&&n&&!w(o,n)||!e&&o)throw o}f.AssertionError=function(e){var t;this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=d(g((t=this).actual),128)+" "+t.operator+" "+d(g(t.expected),128),this.generatedMessage=!0);var n=e.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var o=r.stack,i=p(n),a=o.indexOf("\n"+i);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}},i.inherits(f.AssertionError,Error),f.fail=y,f.ok=v,f.equal=function(e,t,n){e!=t&&y(e,t,n,"==",f.equal)},f.notEqual=function(e,t,n){e==t&&y(e,t,n,"!=",f.notEqual)},f.deepEqual=function(e,t,n){b(e,t,!1)||y(e,t,n,"deepEqual",f.deepEqual)},f.deepStrictEqual=function(e,t,n){b(e,t,!0)||y(e,t,n,"deepStrictEqual",f.deepStrictEqual)},f.notDeepEqual=function(e,t,n){b(e,t,!1)&&y(e,t,n,"notDeepEqual",f.notDeepEqual)},f.notDeepStrictEqual=function e(t,n,r){b(t,n,!0)&&y(t,n,r,"notDeepStrictEqual",e)},f.strictEqual=function(e,t,n){e!==t&&y(e,t,n,"===",f.strictEqual)},f.notStrictEqual=function(e,t,n){e===t&&y(e,t,n,"!==",f.notStrictEqual)},f.throws=function(e,t,n){E(!0,e,t,n)},f.doesNotThrow=function(e,t,n){E(!1,e,t,n)},f.ifError=function(e){if(e)throw e};var S=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(9))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t,n){e.exports=n(10)},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t){},function(e,t,n){"use strict";var r=n(14).Buffer,o=n(60);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){var r=n(6),o=r.Buffer;function i(e,t){for(var n in e)t[n]=e[n]}function a(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=a),i(o,a),a.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},a.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(63),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(9))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,c=1,u={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick(function(){d(e)})}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=c,e.exports.encoder=s},function(e,t,n){(t=e.exports=n(36)).Stream=t,t.Readable=t,t.Writable=n(41),t.Duplex=n(10),t.Transform=n(42),t.PassThrough=n(67)},function(e,t,n){"use strict";e.exports=i;var r=n(42),o=n(21);function i(e){if(!(this instanceof i))return new i(e);r.call(this,e)}o.inherits=n(15),o.inherits(i,r),i.prototype._transform=function(e,t,n){n(null,e)}},function(e,t,n){var r=n(22);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(34).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:throw new Error("map too big to decode in JS");case 212:return c(e,r,1);case 213:return c(e,r,2);case 214:return c(e,r,4);case 215:return c(e,r,8);case 216:return c(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?u(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?u(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?u(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],c=0;for(t+=o,a=0;ai)&&((n=r.allocUnsafe(9))[0]=203,n.writeDoubleBE(e,1)),n}e.exports=function(e,t,n,i){function s(c,u){var l,f,h;if(void 0===c)throw new Error("undefined is not encodable in msgpack!");if(null===c)(l=r.allocUnsafe(1))[0]=192;else if(!0===c)(l=r.allocUnsafe(1))[0]=195;else if(!1===c)(l=r.allocUnsafe(1))[0]=194;else if("string"==typeof c)(f=r.byteLength(c))<32?((l=r.allocUnsafe(1+f))[0]=160|f,f>0&&l.write(c,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(c,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(c,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(c,5));else if(c&&(c.readUInt32LE||c instanceof Uint8Array))c instanceof Uint8Array&&(c=r.from(c)),c.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=c.length):c.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(c.length,1)),l=o([l,c]);else if(Array.isArray(c))c.length<16?(l=r.allocUnsafe(1))[0]=144|c.length:c.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(c.length,1)),l=c.reduce(function(e,t){return e.append(s(t,!0)),e},o().append(l));else{if(!i&&"function"==typeof c.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=new r(10))[0]=215,t[1]=-1;var s=4*a,c=i/Math.pow(2,32),u=s+c&4294967295,l=4294967295&i;t.writeInt32BE(u,2),t.writeInt32BE(l,6)}else(t=new r(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(c);if("object"==typeof c)l=function(t){var n,i,a=-1,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(c)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1));return i.unshift(n),i.reduce(function(e,t){return e.append(t)},o())}(c);else if("number"==typeof c){if((h=c)!==Math.floor(h))return a(c,t);if(c>=0)if(c<128)(l=r.allocUnsafe(1))[0]=c;else if(c<256)(l=r.allocUnsafe(2))[0]=204,l[1]=c;else if(c<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(c,1);else if(c<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(c,1);else{if(!(c<=9007199254740991))return a(c,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,c)}else if(c>=-32)(l=r.allocUnsafe(1))[0]=256+c;else if(c>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(c,1);else if(c>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(c,1);else if(c>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(c,1);else{if(!(c>=-9007199254740991))return a(c,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var c=(255^e[s])+a;e[s]=255&c,a=c>>8}}(l,1,c)}}}if(!l)throw new Error("not implemented yet");return u?l:l.slice()}return s}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId?this.fatalError?(this.logger.log(s.LogLevel.Debug,"Received a new batch "+e+" but errored out on a previous batch "+(this.nextBatchId-1)),[4,n.send("OnRenderCompleted",this.nextBatchId-1,this.fatalError.toString())]):[3,4]:[3,5];case 3:return o.sent(),[2];case 4:return this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed."),[2];case 5:return o.trys.push([5,7,,8]),this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),[4,this.completeBatch(n,e)];case 6:return o.sent(),[3,8];case 7:throw r=o.sent(),this.fatalError=r.toString(),this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,r.toString()),r;case 8:return[2]}})})},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,function(){return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}})})},e}();t.RenderQueue=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(72),o=Math.pow(2,32),i=Math.pow(2,21)-1,a=function(){function e(e){this.batchData=e;var t=new l(e);this.arrayRangeReader=new f(e),this.arrayBuilderSegmentReader=new h(e),this.diffReader=new s(e),this.editReader=new c(e,t),this.frameReader=new u(e,t)}return e.prototype.updatedComponents=function(){return p(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return p(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return p(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return p(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return p(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+20*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return p(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+8*t;return g(this.batchData,n)},e}();t.OutOfProcessRenderBatch=a;var s=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return p(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),c=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return p(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return p(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return p(this.batchDataUint8,e+8)},e.prototype.moveToSiblingIndex=function(e){return p(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=p(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),u=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return p(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return p(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return p(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=p(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=p(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return g(this.batchDataUint8,e+12)},e}(),l=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=p(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t,n=p(this.batchDataUint8,this.stringTableStartIndex+4*e),o=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<>>0)}function g(e,t){var n=d(e,t+4);if(n>i)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*o+d(e,t)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof TextDecoder?new TextDecoder("utf-8"):null;t.decodeUtf8=r?r.decode.bind(r):function(e){var t=0,n=e.length,r=[],o=[];for(;t65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}();t.NullLogger=o;var i=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]reloading the page if you're unable to reconnect.",this.message.querySelector("a").addEventListener("click",function(){return location.reload()})},e.prototype.rejected=function(){this.button.style.display="none",this.reloadParagraph.style.display="none",this.message.innerHTML="Could not reconnect to the server. Reload the page to restore functionality.",this.message.querySelector("a").addEventListener("click",function(){return location.reload()})},e}();t.DefaultReconnectDisplay=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.dialog=e}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.rejected=function(){this.removeClasses(),this.dialog.classList.add(e.RejectedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName,e.RejectedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e.RejectedClassName="components-reconnect-rejected",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";n.r(t);var r=n(6),o=n(11),i=n(2),a=function(){function e(){}return e.write=function(e){var t=e.byteLength||e.length,n=[];do{var r=127&t;(t>>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=new Uint8Array([145,i.MessageType.Ping]),c=function(){function e(){this.name="messagepack",this.version=1,this.transferFormat=i.TransferFormat.Binary,this.errorResult=1,this.voidResult=2,this.nonVoidResult=3}return e.prototype.parseMessages=function(e,t){if(!(e instanceof r.Buffer||(n=e,n&&"undefined"!=typeof ArrayBuffer&&(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer.");var n;null===t&&(t=i.NullLogger.instance);for(var o=[],s=0,c=a.parse(e);s=3?e[2]:void 0,error:e[1],type:i.MessageType.Close}},e.prototype.createPingMessage=function(e){if(e.length<1)throw new Error("Invalid payload for Ping message.");return{type:i.MessageType.Ping}},e.prototype.createInvocationMessage=function(e,t){if(t.length<5)throw new Error("Invalid payload for Invocation message.");var n=t[2];return n?{arguments:t[4],headers:e,invocationId:n,streamIds:[],target:t[3],type:i.MessageType.Invocation}:{arguments:t[4],headers:e,streamIds:[],target:t[3],type:i.MessageType.Invocation}},e.prototype.createStreamItemMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for StreamItem message.");return{headers:e,invocationId:t[2],item:t[3],type:i.MessageType.StreamItem}},e.prototype.createCompletionMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for Completion message.");var n,r,o=t[3];if(o!==this.voidResult&&t.length<5)throw new Error("Invalid payload for Completion message.");switch(o){case this.errorResult:n=t[4];break;case this.nonVoidResult:r=t[4]}return{error:n,headers:e,invocationId:t[2],result:r,type:i.MessageType.Completion}},e.prototype.writeInvocation=function(e){var t=o().encode([i.MessageType.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments,e.streamIds]);return a.write(t.slice())},e.prototype.writeStreamInvocation=function(e){var t=o().encode([i.MessageType.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments,e.streamIds]);return a.write(t.slice())},e.prototype.writeStreamItem=function(e){var t=o().encode([i.MessageType.StreamItem,e.headers||{},e.invocationId,e.item]);return a.write(t.slice())},e.prototype.writeCompletion=function(e){var t,n=o(),r=e.error?this.errorResult:e.result?this.nonVoidResult:this.voidResult;switch(r){case this.errorResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.error]);break;case this.voidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r]);break;case this.nonVoidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.result])}return a.write(t.slice())},e.prototype.writeCancelInvocation=function(e){var t=o().encode([i.MessageType.CancelInvocation,e.headers||{},e.invocationId]);return a.write(t.slice())},e.prototype.readHeaders=function(e){var t=e[1];if("object"!=typeof t)throw new Error("Invalid headers.");return t},e}();n.d(t,"VERSION",function(){return u}),n.d(t,"MessagePackHubProtocol",function(){return c});var u="3.1.0"}]); \ No newline at end of file +function r(e,t){if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);o=0;u--)if(l[u]!==f[u])return!1;for(u=l.length-1;u>=0;u--)if(c=l[u],!b(e[c],t[c],n,r))return!1;return!0}(e,t,n,a))}return n?e===t:e==t}function m(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function w(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function E(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&y(o,n,"Missing expected exception"+r);var a="string"==typeof r,s=!e&&o&&!n;if((!e&&i.isError(o)&&a&&w(o,n)||s)&&y(o,n,"Got unwanted exception"+r),e&&o&&n&&!w(o,n)||!e&&o)throw o}f.AssertionError=function(e){var t;this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=d(g((t=this).actual),128)+" "+t.operator+" "+d(g(t.expected),128),this.generatedMessage=!0);var n=e.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var o=r.stack,i=p(n),a=o.indexOf("\n"+i);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}},i.inherits(f.AssertionError,Error),f.fail=y,f.ok=v,f.equal=function(e,t,n){e!=t&&y(e,t,n,"==",f.equal)},f.notEqual=function(e,t,n){e==t&&y(e,t,n,"!=",f.notEqual)},f.deepEqual=function(e,t,n){b(e,t,!1)||y(e,t,n,"deepEqual",f.deepEqual)},f.deepStrictEqual=function(e,t,n){b(e,t,!0)||y(e,t,n,"deepStrictEqual",f.deepStrictEqual)},f.notDeepEqual=function(e,t,n){b(e,t,!1)&&y(e,t,n,"notDeepEqual",f.notDeepEqual)},f.notDeepStrictEqual=function e(t,n,r){b(t,n,!0)&&y(t,n,r,"notDeepStrictEqual",e)},f.strictEqual=function(e,t,n){e!==t&&y(e,t,n,"===",f.strictEqual)},f.notStrictEqual=function(e,t,n){e===t&&y(e,t,n,"!==",f.notStrictEqual)},f.throws=function(e,t,n){E(!0,e,t,n)},f.doesNotThrow=function(e,t,n){E(!1,e,t,n)},f.ifError=function(e){if(e)throw e};var S=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(9))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t,n){e.exports=n(10)},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t){},function(e,t,n){"use strict";var r=n(15).Buffer,o=n(60);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){var r=n(6),o=r.Buffer;function i(e,t){for(var n in e)t[n]=e[n]}function a(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=a),i(o,a),a.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},a.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(63),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(9))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,c=1,u={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick(function(){d(e)})}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=c,e.exports.encoder=s},function(e,t,n){(t=e.exports=n(36)).Stream=t,t.Readable=t,t.Writable=n(41),t.Duplex=n(10),t.Transform=n(42),t.PassThrough=n(67)},function(e,t,n){"use strict";e.exports=i;var r=n(42),o=n(21);function i(e){if(!(this instanceof i))return new i(e);r.call(this,e)}o.inherits=n(16),o.inherits(i,r),i.prototype._transform=function(e,t,n){n(null,e)}},function(e,t,n){var r=n(22);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(34).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:throw new Error("map too big to decode in JS");case 212:return c(e,r,1);case 213:return c(e,r,2);case 214:return c(e,r,4);case 215:return c(e,r,8);case 216:return c(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?u(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?u(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?u(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],c=0;for(t+=o,a=0;ai)&&((n=r.allocUnsafe(9))[0]=203,n.writeDoubleBE(e,1)),n}e.exports=function(e,t,n,i){function s(c,u){var l,f,h;if(void 0===c)throw new Error("undefined is not encodable in msgpack!");if(null===c)(l=r.allocUnsafe(1))[0]=192;else if(!0===c)(l=r.allocUnsafe(1))[0]=195;else if(!1===c)(l=r.allocUnsafe(1))[0]=194;else if("string"==typeof c)(f=r.byteLength(c))<32?((l=r.allocUnsafe(1+f))[0]=160|f,f>0&&l.write(c,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(c,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(c,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(c,5));else if(c&&(c.readUInt32LE||c instanceof Uint8Array))c instanceof Uint8Array&&(c=r.from(c)),c.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=c.length):c.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(c.length,1)),l=o([l,c]);else if(Array.isArray(c))c.length<16?(l=r.allocUnsafe(1))[0]=144|c.length:c.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(c.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(c.length,1)),l=c.reduce(function(e,t){return e.append(s(t,!0)),e},o().append(l));else{if(!i&&"function"==typeof c.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=new r(10))[0]=215,t[1]=-1;var s=4*a,c=i/Math.pow(2,32),u=s+c&4294967295,l=4294967295&i;t.writeInt32BE(u,2),t.writeInt32BE(l,6)}else(t=new r(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(c);if("object"==typeof c)l=function(t){var n,i,a=-1,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(c)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1));return i.unshift(n),i.reduce(function(e,t){return e.append(t)},o())}(c);else if("number"==typeof c){if((h=c)!==Math.floor(h))return a(c,t);if(c>=0)if(c<128)(l=r.allocUnsafe(1))[0]=c;else if(c<256)(l=r.allocUnsafe(2))[0]=204,l[1]=c;else if(c<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(c,1);else if(c<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(c,1);else{if(!(c<=9007199254740991))return a(c,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,c)}else if(c>=-32)(l=r.allocUnsafe(1))[0]=256+c;else if(c>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(c,1);else if(c>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(c,1);else if(c>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(c,1);else{if(!(c>=-9007199254740991))return a(c,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var c=(255^e[s])+a;e[s]=255&c,a=c>>8}}(l,1,c)}}}if(!l)throw new Error("not implemented yet");return u?l:l.slice()}return s}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId?this.fatalError?(this.logger.log(s.LogLevel.Debug,"Received a new batch "+e+" but errored out on a previous batch "+(this.nextBatchId-1)),[4,n.send("OnRenderCompleted",this.nextBatchId-1,this.fatalError.toString())]):[3,4]:[3,5];case 3:return o.sent(),[2];case 4:return this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed."),[2];case 5:return o.trys.push([5,7,,8]),this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),[4,this.completeBatch(n,e)];case 6:return o.sent(),[3,8];case 7:throw r=o.sent(),this.fatalError=r.toString(),this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,r.toString()),r;case 8:return[2]}})})},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,function(){return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}})})},e}();t.RenderQueue=c},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(72),o=Math.pow(2,32),i=Math.pow(2,21)-1,a=function(){function e(e){this.batchData=e;var t=new l(e);this.arrayRangeReader=new f(e),this.arrayBuilderSegmentReader=new h(e),this.diffReader=new s(e),this.editReader=new c(e,t),this.frameReader=new u(e,t)}return e.prototype.updatedComponents=function(){return p(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return p(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return p(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return p(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return p(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+20*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return p(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+8*t;return g(this.batchData,n)},e}();t.OutOfProcessRenderBatch=a;var s=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return p(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),c=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return p(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return p(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return p(this.batchDataUint8,e+8)},e.prototype.moveToSiblingIndex=function(e){return p(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=p(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),u=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return p(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return p(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return p(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=p(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=p(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=p(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return g(this.batchDataUint8,e+12)},e}(),l=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=p(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t,n=p(this.batchDataUint8,this.stringTableStartIndex+4*e),o=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<>>0)}function g(e,t){var n=d(e,t+4);if(n>i)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*o+d(e,t)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r="function"==typeof TextDecoder?new TextDecoder("utf-8"):null;t.decodeUtf8=r?r.decode.bind(r):function(e){var t=0,n=e.length,r=[],o=[];for(;t65535&&(u-=65536,r.push(u>>>10&1023|55296),u=56320|1023&u),r.push(u)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(17),o=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}();t.NullLogger=o;var i=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{c(r.next(e))}catch(e){i(e)}}function s(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}c((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]reloading the page if you're unable to reconnect.",this.message.querySelector("a").addEventListener("click",function(){return location.reload()})},e.prototype.rejected=function(){this.button.style.display="none",this.reloadParagraph.style.display="none",this.message.innerHTML="Could not reconnect to the server. Reload the page to restore functionality.",this.message.querySelector("a").addEventListener("click",function(){return location.reload()})},e}();t.DefaultReconnectDisplay=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.dialog=e}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.rejected=function(){this.removeClasses(),this.dialog.classList.add(e.RejectedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName,e.RejectedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e.RejectedClassName="components-reconnect-rejected",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";n.r(t);var r=n(6),o=n(11),i=n(2),a=function(){function e(){}return e.write=function(e){var t=e.byteLength||e.length,n=[];do{var r=127&t;(t>>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=new Uint8Array([145,i.MessageType.Ping]),c=function(){function e(){this.name="messagepack",this.version=1,this.transferFormat=i.TransferFormat.Binary,this.errorResult=1,this.voidResult=2,this.nonVoidResult=3}return e.prototype.parseMessages=function(e,t){if(!(e instanceof r.Buffer||(n=e,n&&"undefined"!=typeof ArrayBuffer&&(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer.");var n;null===t&&(t=i.NullLogger.instance);for(var o=[],s=0,c=a.parse(e);s=3?e[2]:void 0,error:e[1],type:i.MessageType.Close}},e.prototype.createPingMessage=function(e){if(e.length<1)throw new Error("Invalid payload for Ping message.");return{type:i.MessageType.Ping}},e.prototype.createInvocationMessage=function(e,t){if(t.length<5)throw new Error("Invalid payload for Invocation message.");var n=t[2];return n?{arguments:t[4],headers:e,invocationId:n,streamIds:[],target:t[3],type:i.MessageType.Invocation}:{arguments:t[4],headers:e,streamIds:[],target:t[3],type:i.MessageType.Invocation}},e.prototype.createStreamItemMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for StreamItem message.");return{headers:e,invocationId:t[2],item:t[3],type:i.MessageType.StreamItem}},e.prototype.createCompletionMessage=function(e,t){if(t.length<4)throw new Error("Invalid payload for Completion message.");var n,r,o=t[3];if(o!==this.voidResult&&t.length<5)throw new Error("Invalid payload for Completion message.");switch(o){case this.errorResult:n=t[4];break;case this.nonVoidResult:r=t[4]}return{error:n,headers:e,invocationId:t[2],result:r,type:i.MessageType.Completion}},e.prototype.writeInvocation=function(e){var t=o().encode([i.MessageType.Invocation,e.headers||{},e.invocationId||null,e.target,e.arguments,e.streamIds]);return a.write(t.slice())},e.prototype.writeStreamInvocation=function(e){var t=o().encode([i.MessageType.StreamInvocation,e.headers||{},e.invocationId,e.target,e.arguments,e.streamIds]);return a.write(t.slice())},e.prototype.writeStreamItem=function(e){var t=o().encode([i.MessageType.StreamItem,e.headers||{},e.invocationId,e.item]);return a.write(t.slice())},e.prototype.writeCompletion=function(e){var t,n=o(),r=e.error?this.errorResult:e.result?this.nonVoidResult:this.voidResult;switch(r){case this.errorResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.error]);break;case this.voidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r]);break;case this.nonVoidResult:t=n.encode([i.MessageType.Completion,e.headers||{},e.invocationId,r,e.result])}return a.write(t.slice())},e.prototype.writeCancelInvocation=function(e){var t=o().encode([i.MessageType.CancelInvocation,e.headers||{},e.invocationId]);return a.write(t.slice())},e.prototype.readHeaders=function(e){var t=e[1];if("object"!=typeof t)throw new Error("Invalid headers.");return t},e}();n.d(t,"VERSION",function(){return u}),n.d(t,"MessagePackHubProtocol",function(){return c});var u="0.0.0-DEV_BUILD"}]); \ No newline at end of file diff --git a/src/Components/Web.JS/dist/Release/blazor.webassembly.js b/src/Components/Web.JS/dist/Release/blazor.webassembly.js index 9f9d6b369d..a788a1c44f 100644 --- a/src/Components/Web.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Web.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=45)}([,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(25),n(18);var r=n(26),o=n(13),a={},i=!1;function u(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=u,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");u(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),u=r.values(o),l=r.count(o),s=t.referenceFrames(),c=r.values(s),d=t.diffReader,f=0;f0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===c(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=d(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=c},,,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t,n,r){var o=s();if(o.invokeDotNetFromJS){var a=JSON.stringify(r,h),i=o.invokeDotNetFromJS(e,t,n,a);return i?d(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function l(e,t,r,a){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=o++,u=new Promise(function(e,t){n[i]={resolve:e,reject:t}});try{var l=JSON.stringify(a,h);s().beginInvokeDotNetFromJS(i,e,t,r,l)}catch(e){c(i,!1,e)}return u}function s(){if(null!==a)return a;throw new Error("No .NET call dispatcher has been set.")}function c(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function d(e){return e?JSON.parse(e,function(e,n){return t.reduce(function(t,n){return n(e,t)},n)}):null}function f(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach(function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e}),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){a=e},e.attachReviver=i,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]>2,r=Module.HEAPU32[n+1];if(r>s)throw new Error("Cannot read uint64 with high order part "+r+", because the result would exceed Number.MAX_SAFE_INTEGER.");return r*l+Module.HEAPU32[n]},readFloatField:function(e,t){return Module.getValue(e+(t||0),"float")},readObjectField:function(e,t){return Module.getValue(e+(t||0),"i32")},readStringField:function(e,n){var r=Module.getValue(e+(n||0),"i32");return 0===r?null:t.monoPlatform.toJavaScriptString(r)},readStructField:function(e,t){return e+(t||0)}};var c=document.createElement("a");function d(e){return e+12}function f(e,t,n){var r="["+e+"] "+t+":"+n;return Module.mono_bind_static_method(r)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(35),o=window.chrome&&navigator.userAgent.indexOf("Edge")<0,a=!1;function i(){return a&&o}t.hasDebuggingEnabled=i,t.attachDebuggerHotkey=function(e){a=e.some(function(e){return/\.pdb$/.test(r.getFileNameFromUrl(e))});var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";i()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(a?o?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Edge(Chromium) or Chrome is supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(18),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=a,this.arrayBuilderSegmentReader=i,this.diffReader=u,this.editReader=l,this.frameReader=s}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,a.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*a.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*a.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return c(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return c(e,t,s.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=c(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=c(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var a={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},i={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+i.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return c(e,t,l.structLength)}},l={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},s={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function c(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}}]); \ No newline at end of file +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=45)}([,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(25),n(19);var r=n(26),o=n(13),a={},i=!1;function u(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=u,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");u(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),u=r.values(o),l=r.count(o),s=t.referenceFrames(),c=r.values(s),d=t.diffReader,f=0;f0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return r in e||(e[r]=[]),e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===c(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=d(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=c},,,,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t,n,r){var o=s();if(o.invokeDotNetFromJS){var a=JSON.stringify(r,h),i=o.invokeDotNetFromJS(e,t,n,a);return i?d(i):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function l(e,t,r,a){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var i=o++,u=new Promise(function(e,t){n[i]={resolve:e,reject:t}});try{var l=JSON.stringify(a,h);s().beginInvokeDotNetFromJS(i,e,t,r,l)}catch(e){c(i,!1,e)}return u}function s(){if(null!==a)return a;throw new Error("No .NET call dispatcher has been set.")}function c(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function d(e){return e?JSON.parse(e,function(e,n){return t.reduce(function(t,n){return n(e,t)},n)}):null}function f(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach(function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e}),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){a=e},e.attachReviver=i,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]>2,r=Module.HEAPU32[n+1];if(r>s)throw new Error("Cannot read uint64 with high order part "+r+", because the result would exceed Number.MAX_SAFE_INTEGER.");return r*l+Module.HEAPU32[n]},readFloatField:function(e,t){return Module.getValue(e+(t||0),"float")},readObjectField:function(e,t){return Module.getValue(e+(t||0),"i32")},readStringField:function(e,n){var r=Module.getValue(e+(n||0),"i32");return 0===r?null:t.monoPlatform.toJavaScriptString(r)},readStructField:function(e,t){return e+(t||0)}};var c=document.createElement("a");function d(e){return e+12}function f(e,t,n){var r="["+e+"] "+t+":"+n;return Module.mono_bind_static_method(r)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(35),o=window.chrome&&navigator.userAgent.indexOf("Edge")<0,a=!1;function i(){return a&&o}t.hasDebuggingEnabled=i,t.attachDebuggerHotkey=function(e){a=e.some(function(e){return/\.pdb$/.test(r.getFileNameFromUrl(e))});var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";i()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),document.addEventListener("keydown",function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(a?o?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Edge(Chromium) or Chrome is supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))})}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=a,this.arrayBuilderSegmentReader=i,this.diffReader=u,this.editReader=l,this.frameReader=s}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,a.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*a.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*a.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return c(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return c(e,t,s.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=c(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=c(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var a={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},i={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+i.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return c(e,t,l.structLength)}},l={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},s={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function c(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}}]); \ No newline at end of file diff --git a/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts b/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts index b8f755d8ac..58d9eb7e37 100644 --- a/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts +++ b/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts @@ -22,7 +22,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay { 'right: 0', 'bottom: 0', 'left: 0', - 'z-index: 1000', + 'z-index: 1050', 'display: none', 'overflow: hidden', 'background-color: #fff', diff --git a/src/Components/Web.JS/src/Rendering/BrowserRenderer.ts b/src/Components/Web.JS/src/Rendering/BrowserRenderer.ts index 67a01446b9..6596741509 100644 --- a/src/Components/Web.JS/src/Rendering/BrowserRenderer.ts +++ b/src/Components/Web.JS/src/Rendering/BrowserRenderer.ts @@ -372,7 +372,7 @@ export class BrowserRenderer { } case 'OPTION': { const value = attributeFrame ? frameReader.attributeValue(attributeFrame) : null; - if (value) { + if (value || value === '') { element.setAttribute('value', value); } else { element.removeAttribute('value'); diff --git a/src/Components/Web.JS/src/Rendering/LogicalElements.ts b/src/Components/Web.JS/src/Rendering/LogicalElements.ts index 577c815f58..5b4aac4295 100644 --- a/src/Components/Web.JS/src/Rendering/LogicalElements.ts +++ b/src/Components/Web.JS/src/Rendering/LogicalElements.ts @@ -54,13 +54,14 @@ export function toLogicalRootCommentElement(start: Comment, end: Comment): Logic const parentLogicalElement = toLogicalElement(parent, /* allow existing contents */ true); const children = getLogicalChildrenArray(parentLogicalElement); Array.from(parent.childNodes).forEach(n => children.push(n as unknown as LogicalElement)); + start[logicalParentPropname] = parentLogicalElement; // We might not have an end comment in the case of non-prerendered components. if (end) { start[logicalEndSiblingPropname] = end; - toLogicalElement(end, /* allowExistingcontents */ true); + toLogicalElement(end); } - return toLogicalElement(start, /* allowExistingContents */ true); + return toLogicalElement(start); } export function toLogicalElement(element: Node, allowExistingContents?: boolean): LogicalElement { @@ -71,7 +72,10 @@ export function toLogicalElement(element: Node, allowExistingContents?: boolean) throw new Error('New logical elements must start empty, or allowExistingContents must be true'); } - element[logicalChildrenPropname] = []; + if (!(logicalChildrenPropname in element)) { // If it's already a logical element, leave it alone + element[logicalChildrenPropname] = []; + } + return element as unknown as LogicalElement; } diff --git a/src/Components/Web.JS/src/Services/NavigationManager.ts b/src/Components/Web.JS/src/Services/NavigationManager.ts index 5f217d3659..7b96987a11 100644 --- a/src/Components/Web.JS/src/Services/NavigationManager.ts +++ b/src/Components/Web.JS/src/Services/NavigationManager.ts @@ -81,7 +81,7 @@ export function navigateTo(uri: string, forceLoad: boolean) { } else if (forceLoad && location.href === uri) { // Force-loading the same URL you're already on requires special handling to avoid // triggering browser-specific behavior issues. - // For details about what this fixes and why, see https://github.com/aspnet/AspNetCore/pull/10839 + // For details about what this fixes and why, see https://github.com/dotnet/aspnetcore/pull/10839 const temporaryUri = uri + '?'; history.replaceState(null, '', temporaryUri); location.replace(uri); diff --git a/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netcoreapp.cs b/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netcoreapp.cs index 4928dc03fd..15e4665454 100644 --- a/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netcoreapp.cs +++ b/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netcoreapp.cs @@ -7,12 +7,12 @@ namespace Microsoft.AspNetCore.Components public sealed partial class BindInputElementAttribute : System.Attribute { public BindInputElementAttribute(string type, string suffix, string valueAttribute, string changeAttribute, bool isInvariantCulture, string format) { } - public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsInvariantCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsInvariantCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Components.Forms @@ -26,19 +26,19 @@ namespace Microsoft.AspNetCore.Components.Forms { public EditForm() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback OnInvalidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback OnInvalidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback OnSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback OnSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback OnValidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback OnValidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override void OnParametersSet() { } } @@ -46,18 +46,18 @@ namespace Microsoft.AspNetCore.Components.Forms { protected InputBase() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected string CssClass { get { throw null; } } protected TValue CurrentValue { get { throw null; } set { } } protected string CurrentValueAsString { get { throw null; } set { } } - protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Linq.Expressions.Expression> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Linq.Expressions.Expression> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected virtual void Dispose(bool disposing) { } protected virtual string FormatValueAsString(TValue value) { throw null; } public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Components.Forms { public InputDate() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override string FormatValueAsString(TValue value) { throw null; } protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; } @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Components.Forms { public InputNumber() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override string FormatValueAsString(TValue value) { throw null; } protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; } @@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Components.Forms { public InputSelect() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; } } @@ -112,9 +112,9 @@ namespace Microsoft.AspNetCore.Components.Forms { public ValidationMessage() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Linq.Expressions.Expression> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Linq.Expressions.Expression> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected virtual void Dispose(bool disposing) { } protected override void OnParametersSet() { } @@ -124,9 +124,9 @@ namespace Microsoft.AspNetCore.Components.Forms { public ValidationSummary() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected virtual void Dispose(bool disposing) { } protected override void OnParametersSet() { } @@ -138,10 +138,10 @@ namespace Microsoft.AspNetCore.Components.RenderTree public sealed partial class WebEventDescriptor { public WebEventDescriptor() { } - public int BrowserRendererId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo EventFieldInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public ulong EventHandlerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int BrowserRendererId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo EventFieldInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public ulong EventHandlerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Components.Routing @@ -150,14 +150,14 @@ namespace Microsoft.AspNetCore.Components.Routing { public NavLink() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string ActiveClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ActiveClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected string CssClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected string CssClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.Routing.NavLinkMatch Match { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.Routing.NavLinkMatch Match { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } public void Dispose() { } protected override void OnInitialized() { } @@ -193,36 +193,36 @@ namespace Microsoft.AspNetCore.Components.Web public partial class ClipboardEventArgs : System.EventArgs { public ClipboardEventArgs() { } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DataTransfer { public DataTransfer() { } - public string DropEffect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EffectAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] Files { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.DataTransferItem[] Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] Types { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string DropEffect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EffectAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] Files { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.DataTransferItem[] Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] Types { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DataTransferItem { public DataTransferItem() { } - public string Kind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Kind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DragEventArgs : Microsoft.AspNetCore.Components.Web.MouseEventArgs { public DragEventArgs() { } - public Microsoft.AspNetCore.Components.Web.DataTransfer DataTransfer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.Web.DataTransfer DataTransfer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ErrorEventArgs : System.EventArgs { public ErrorEventArgs() { } - public int Colno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Filename { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Lineno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Colno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Filename { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Lineno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [Microsoft.AspNetCore.Components.EventHandlerAttribute("onabort", typeof(Microsoft.AspNetCore.Components.Web.ProgressEventArgs), true, true)] [Microsoft.AspNetCore.Components.EventHandlerAttribute("onactivate", typeof(System.EventArgs), true, true)] @@ -321,80 +321,80 @@ namespace Microsoft.AspNetCore.Components.Web public partial class FocusEventArgs : System.EventArgs { public FocusEventArgs() { } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class KeyboardEventArgs : System.EventArgs { public KeyboardEventArgs() { } - public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Repeat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Repeat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class MouseEventArgs : System.EventArgs { public MouseEventArgs() { } - public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Button { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Buttons { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Button { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Buttons { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PointerEventArgs : Microsoft.AspNetCore.Components.Web.MouseEventArgs { public PointerEventArgs() { } - public float Height { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsPrimary { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long PointerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PointerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float Pressure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float TiltX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float TiltY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float Width { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public float Height { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsPrimary { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long PointerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PointerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float Pressure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float TiltX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float TiltY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float Width { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ProgressEventArgs : System.EventArgs { public ProgressEventArgs() { } - public bool LengthComputable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Loaded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Total { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool LengthComputable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Loaded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Total { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TouchEventArgs : System.EventArgs { public TouchEventArgs() { } - public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.TouchPoint[] ChangedTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.TouchPoint[] TargetTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.TouchPoint[] Touches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.TouchPoint[] ChangedTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.TouchPoint[] TargetTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.TouchPoint[] Touches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TouchPoint { public TouchPoint() { } - public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double PageX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double PageY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double PageX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double PageY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class WebEventCallbackFactoryEventArgsExtensions { @@ -427,9 +427,9 @@ namespace Microsoft.AspNetCore.Components.Web public partial class WheelEventArgs : Microsoft.AspNetCore.Components.Web.MouseEventArgs { public WheelEventArgs() { } - public long DeltaMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double DeltaX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double DeltaY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double DeltaZ { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public long DeltaMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double DeltaX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double DeltaY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double DeltaZ { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netstandard2.0.cs b/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netstandard2.0.cs index 4928dc03fd..15e4665454 100644 --- a/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netstandard2.0.cs +++ b/src/Components/Web/ref/Microsoft.AspNetCore.Components.Web.netstandard2.0.cs @@ -7,12 +7,12 @@ namespace Microsoft.AspNetCore.Components public sealed partial class BindInputElementAttribute : System.Attribute { public BindInputElementAttribute(string type, string suffix, string valueAttribute, string changeAttribute, bool isInvariantCulture, string format) { } - public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsInvariantCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ChangeAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsInvariantCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Suffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ValueAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Components.Forms @@ -26,19 +26,19 @@ namespace Microsoft.AspNetCore.Components.Forms { public EditForm() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback OnInvalidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback OnInvalidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback OnSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback OnSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback OnValidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback OnValidSubmit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override void OnParametersSet() { } } @@ -46,18 +46,18 @@ namespace Microsoft.AspNetCore.Components.Forms { protected InputBase() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected string CssClass { get { throw null; } } protected TValue CurrentValue { get { throw null; } set { } } protected string CurrentValueAsString { get { throw null; } set { } } - protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.EventCallback ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.EventCallback ValueChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Linq.Expressions.Expression> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Linq.Expressions.Expression> ValueExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected virtual void Dispose(bool disposing) { } protected virtual string FormatValueAsString(TValue value) { throw null; } public override System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) { throw null; } @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Components.Forms { public InputDate() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override string FormatValueAsString(TValue value) { throw null; } protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; } @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Components.Forms { public InputNumber() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ParsingErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override string FormatValueAsString(TValue value) { throw null; } protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; } @@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Components.Forms { public InputSelect() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage) { throw null; } } @@ -112,9 +112,9 @@ namespace Microsoft.AspNetCore.Components.Forms { public ValidationMessage() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public System.Linq.Expressions.Expression> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Linq.Expressions.Expression> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected virtual void Dispose(bool disposing) { } protected override void OnParametersSet() { } @@ -124,9 +124,9 @@ namespace Microsoft.AspNetCore.Components.Forms { public ValidationSummary() { } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected virtual void Dispose(bool disposing) { } protected override void OnParametersSet() { } @@ -138,10 +138,10 @@ namespace Microsoft.AspNetCore.Components.RenderTree public sealed partial class WebEventDescriptor { public WebEventDescriptor() { } - public int BrowserRendererId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo EventFieldInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public ulong EventHandlerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int BrowserRendererId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EventArgsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo EventFieldInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public ulong EventHandlerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Components.Routing @@ -150,14 +150,14 @@ namespace Microsoft.AspNetCore.Components.Routing { public NavLink() { } [Microsoft.AspNetCore.Components.ParameterAttribute] - public string ActiveClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ActiveClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)] - public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyDictionary AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected string CssClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.RenderFragment ChildContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected string CssClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Components.ParameterAttribute] - public Microsoft.AspNetCore.Components.Routing.NavLinkMatch Match { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.Routing.NavLinkMatch Match { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } public void Dispose() { } protected override void OnInitialized() { } @@ -193,36 +193,36 @@ namespace Microsoft.AspNetCore.Components.Web public partial class ClipboardEventArgs : System.EventArgs { public ClipboardEventArgs() { } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DataTransfer { public DataTransfer() { } - public string DropEffect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EffectAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] Files { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.DataTransferItem[] Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] Types { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string DropEffect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EffectAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] Files { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.DataTransferItem[] Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] Types { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DataTransferItem { public DataTransferItem() { } - public string Kind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Kind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DragEventArgs : Microsoft.AspNetCore.Components.Web.MouseEventArgs { public DragEventArgs() { } - public Microsoft.AspNetCore.Components.Web.DataTransfer DataTransfer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Components.Web.DataTransfer DataTransfer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ErrorEventArgs : System.EventArgs { public ErrorEventArgs() { } - public int Colno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Filename { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Lineno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Colno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Filename { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Lineno { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [Microsoft.AspNetCore.Components.EventHandlerAttribute("onabort", typeof(Microsoft.AspNetCore.Components.Web.ProgressEventArgs), true, true)] [Microsoft.AspNetCore.Components.EventHandlerAttribute("onactivate", typeof(System.EventArgs), true, true)] @@ -321,80 +321,80 @@ namespace Microsoft.AspNetCore.Components.Web public partial class FocusEventArgs : System.EventArgs { public FocusEventArgs() { } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class KeyboardEventArgs : System.EventArgs { public KeyboardEventArgs() { } - public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Repeat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Repeat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class MouseEventArgs : System.EventArgs { public MouseEventArgs() { } - public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Button { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Buttons { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Button { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Buttons { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PointerEventArgs : Microsoft.AspNetCore.Components.Web.MouseEventArgs { public PointerEventArgs() { } - public float Height { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsPrimary { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long PointerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PointerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float Pressure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float TiltX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float TiltY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public float Width { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public float Height { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsPrimary { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long PointerId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PointerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float Pressure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float TiltX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float TiltY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public float Width { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ProgressEventArgs : System.EventArgs { public ProgressEventArgs() { } - public bool LengthComputable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Loaded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Total { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool LengthComputable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Loaded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Total { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TouchEventArgs : System.EventArgs { public TouchEventArgs() { } - public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.TouchPoint[] ChangedTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.TouchPoint[] TargetTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Components.Web.TouchPoint[] Touches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AltKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.TouchPoint[] ChangedTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool CtrlKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool MetaKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShiftKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.TouchPoint[] TargetTouches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Components.Web.TouchPoint[] Touches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TouchPoint { public TouchPoint() { } - public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double PageX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double PageY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public double ClientX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ClientY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double PageX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double PageY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double ScreenY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class WebEventCallbackFactoryEventArgsExtensions { @@ -427,9 +427,9 @@ namespace Microsoft.AspNetCore.Components.Web public partial class WheelEventArgs : Microsoft.AspNetCore.Components.Web.MouseEventArgs { public WheelEventArgs() { } - public long DeltaMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double DeltaX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double DeltaY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public double DeltaZ { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public long DeltaMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double DeltaX { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double DeltaY { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public double DeltaZ { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Components/Web/src/BindInputElementAttribute.cs b/src/Components/Web/src/BindInputElementAttribute.cs index 0cba1a8e84..f6169c0ca5 100644 --- a/src/Components/Web/src/BindInputElementAttribute.cs +++ b/src/Components/Web/src/BindInputElementAttribute.cs @@ -7,7 +7,7 @@ using System.Globalization; namespace Microsoft.AspNetCore.Components { /// - /// Configures options for binding subtypes of an HTML input element. + /// Configures options for binding subtypes of an HTML input element. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] public sealed class BindInputElementAttribute : Attribute @@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Components /// /// Constructs an instance of . /// - /// The value of the element's type attribute. + /// The value of the element's type attribute. /// The suffix value. /// The name of the value attribute to be bound. /// The name of an attribute that will register an associated change event. @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Components } /// - /// Gets the value of the element's type attribute. + /// Gets the value of the element's type attribute. /// public string Type { get; } diff --git a/src/Components/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs index 5b2a08a3b8..09327bcae6 100644 --- a/src/Components/Web/src/Forms/InputNumber.cs +++ b/src/Components/Web/src/Forms/InputNumber.cs @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Components.Forms } /// - /// Formats the value as a string. Derived classes can override this to determine the formating used for CurrentValueAsString. + /// Formats the value as a string. Derived classes can override this to determine the formatting used for CurrentValueAsString. /// /// The value to format. /// A string representation of the value. diff --git a/src/Components/Web/test/Forms/InputBaseTest.cs b/src/Components/Web/test/Forms/InputBaseTest.cs index ce1bf7bfa2..285361d538 100644 --- a/src/Components/Web/test/Forms/InputBaseTest.cs +++ b/src/Components/Web/test/Forms/InputBaseTest.cs @@ -212,7 +212,7 @@ namespace Microsoft.AspNetCore.Components.Forms }; var fieldIdentifier = FieldIdentifier.Create(() => model.StringProperty); - // Act/Assert: Initally, it's valid and unmodified + // Act/Assert: Initially, it's valid and unmodified var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent); Assert.Equal("valid", inputComponent.CssClass); // no Class was specified diff --git a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj index ac69ac235a..0ba4c8311a 100644 --- a/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj +++ b/src/Components/test/E2ETest/Microsoft.AspNetCore.Components.E2ETests.csproj @@ -7,10 +7,7 @@ $(DefaultNetCoreTargetFramework) Components.E2ETests - - true - - + false diff --git a/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs b/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs index 76a01c13f3..3e330f7b47 100644 --- a/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs +++ b/src/Components/test/E2ETest/ServerExecutionTests/GlobalizationTest.cs @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests [Theory] [InlineData("en-US")] [InlineData("fr-FR")] - public void CanSetCultureAndParseCultueSensitiveNumbersAndDates(string culture) + public void CanSetCultureAndParseCultureSensitiveNumbersAndDates(string culture) { var cultureInfo = CultureInfo.GetCultureInfo(culture); SetCulture(culture); diff --git a/src/Components/test/E2ETest/Tests/BindTest.cs b/src/Components/test/E2ETest/Tests/BindTest.cs index 40e9494a9b..cefd842022 100644 --- a/src/Components/test/E2ETest/Tests/BindTest.cs +++ b/src/Components/test/E2ETest/Tests/BindTest.cs @@ -214,6 +214,11 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests Browser.FindElement(By.Id("select-box-add-option")).Click(); Browser.Equal("Fourth", () => boundValue.Text); Assert.Equal("Fourth choice", target.SelectedOption.Text); + + // Verify we can select options whose value is empty + // https://github.com/dotnet/aspnetcore/issues/17735 + target.SelectByText("Empty value"); + Browser.Equal(string.Empty, () => boundValue.Text); } [Fact] @@ -227,6 +232,11 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests // Modify target; verify value is updated target.SelectByText("Third choice"); Browser.Equal("Third", () => boundValue.Text); + + // Verify we can select options whose value is empty + // https://github.com/dotnet/aspnetcore/issues/17735 + target.SelectByText("Empty value"); + Browser.Equal(string.Empty, () => boundValue.Text); } [Fact] diff --git a/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs b/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs index fa93b85717..ca9af22c99 100644 --- a/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs +++ b/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs @@ -626,7 +626,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests Browser.Exists(incompleteItemsSelector); // Mark first item as done; observe the remaining incomplete item appears unchecked - // because the diff algoritm explicitly unchecks it + // because the diff algorithm explicitly unchecks it appElement.FindElement(By.CssSelector(".incomplete-items .item-isdone")).Click(); Browser.True(() => { @@ -636,7 +636,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests }); // Mark first done item as not done; observe the remaining complete item appears checked - // because the diff algoritm explicitly re-checks it + // because the diff algorithm explicitly re-checks it appElement.FindElement(By.CssSelector(".complete-items .item-isdone")).Click(); Browser.True(() => { diff --git a/src/Components/test/E2ETest/Tests/EventTest.cs b/src/Components/test/E2ETest/Tests/EventTest.cs index 5cbf1c3ac2..6b29f6b96d 100644 --- a/src/Components/test/E2ETest/Tests/EventTest.cs +++ b/src/Components/test/E2ETest/Tests/EventTest.cs @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests // up for a bit it doesn't cause typing to lose keystrokes. But when running server-side, this // shows that network latency doesn't cause keystrokes to be lost even if: // [1] By the time a keystroke event arrives, the event handler ID has since changed - // [2] We have the situation described under "the problem" at https://github.com/aspnet/AspNetCore/issues/8204#issuecomment-493986702 + // [2] We have the situation described under "the problem" at https://github.com/dotnet/aspnetcore/issues/8204#issuecomment-493986702 Browser.MountTestComponent(); diff --git a/src/Components/test/E2ETest/Tests/FormsTest.cs b/src/Components/test/E2ETest/Tests/FormsTest.cs index edd7404f6f..6db7988271 100644 --- a/src/Components/test/E2ETest/Tests/FormsTest.cs +++ b/src/Components/test/E2ETest/Tests/FormsTest.cs @@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests [Fact] public async Task EditFormWorksWithDataAnnotationsValidator() { - var appElement = MountSimpleValidationComponent();; + var appElement = MountSimpleValidationComponent(); var form = appElement.FindElement(By.TagName("form")); var userNameInput = appElement.FindElement(By.ClassName("user-name")).FindElement(By.TagName("input")); var acceptsTermsInput = appElement.FindElement(By.ClassName("accepts-terms")).FindElement(By.TagName("input")); diff --git a/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor b/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor index 71024bffb8..45d5eacdcc 100644 --- a/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/BindCasesComponent.razor @@ -229,6 +229,7 @@ + @@ -368,8 +370,8 @@ bool includeFourthOption = false; enum SelectableValue { First, Second, Third, Fourth } - SelectableValue selectValue = SelectableValue.Second; - SelectableValue selectMarkupValue = SelectableValue.Second; + SelectableValue? selectValue = SelectableValue.Second; + SelectableValue? selectMarkupValue = SelectableValue.Second; void AddAndSelectNewSelectOption() { diff --git a/src/Components/test/testassets/BasicTestApp/ServerReliability/ReliabilityComponent.razor b/src/Components/test/testassets/BasicTestApp/ServerReliability/ReliabilityComponent.razor index 13256fb7bc..77fbab5eb5 100644 --- a/src/Components/test/testassets/BasicTestApp/ServerReliability/ReliabilityComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/ServerReliability/ReliabilityComponent.razor @@ -18,7 +18,7 @@

Error = @errorFailure

- + diff --git a/src/Components/test/testassets/TestServer/Components.TestServer.csproj b/src/Components/test/testassets/TestServer/Components.TestServer.csproj index a627c1160f..b2d0ce094d 100644 --- a/src/Components/test/testassets/TestServer/Components.TestServer.csproj +++ b/src/Components/test/testassets/TestServer/Components.TestServer.csproj @@ -2,14 +2,18 @@ $(DefaultNetCoreTargetFramework) - - true - + + + + + + + diff --git a/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj b/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj index b2e913f352..40698c9d33 100644 --- a/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj +++ b/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj b/src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj index 65086c1969..aeb1c37401 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj +++ b/src/DataProtection/Cryptography.KeyDerivation/ref/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj @@ -1,13 +1,13 @@ - netstandard2.0;netcoreapp2.0 + netstandard2.0;$(DefaultNetCoreTargetFramework) - + diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj b/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj index dea0ee73e2..81fff6400b 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj +++ b/src/DataProtection/Cryptography.KeyDerivation/src/Microsoft.AspNetCore.Cryptography.KeyDerivation.csproj @@ -2,7 +2,7 @@ ASP.NET Core utilities for key derivation. - netstandard2.0;netcoreapp2.0 + netstandard2.0;$(DefaultNetCoreTargetFramework) true true true diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/NetCorePbkdf2Provider.cs b/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/NetCorePbkdf2Provider.cs index 11b8f481bb..d6bd494b1c 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/NetCorePbkdf2Provider.cs +++ b/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/NetCorePbkdf2Provider.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -#if NETCOREAPP2_0 +#if NETCOREAPP using System; using System.Diagnostics; using System.Security.Cryptography; diff --git a/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs b/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs index 9b2ecf1008..a3340b13b2 100644 --- a/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs +++ b/src/DataProtection/Cryptography.KeyDerivation/src/PBKDF2/Pbkdf2Util.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Cryptography.KeyDerivation.PBKDF2 { #if NETSTANDARD2_0 return new ManagedPbkdf2Provider(); -#elif NETCOREAPP2_0 +#elif NETCOREAPP // fastest implementation on .NET Core for Linux/macOS. // Not supported on .NET Framework return new NetCorePbkdf2Provider(); diff --git a/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netcoreapp.cs b/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netcoreapp.cs index 70cd9bfe67..87d5151d97 100644 --- a/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netcoreapp.cs +++ b/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netcoreapp.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.DataProtection public partial class DataProtectionOptions { public DataProtectionOptions() { } - public string ApplicationDiscriminator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ApplicationDiscriminator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class DataProtectionUtilityExtensions { @@ -128,8 +128,8 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class AuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public AuthenticatedEncryptorConfiguration() { } - public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm ValidationAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm ValidationAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class AuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -145,11 +145,11 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class CngCbcAuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public CngCbcAuthenticatedEncryptorConfiguration() { } - public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HashAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HashAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HashAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HashAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class CngCbcAuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -165,9 +165,9 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class CngGcmAuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public CngGcmAuthenticatedEncryptorConfiguration() { } - public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class CngGcmAuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -191,9 +191,9 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class ManagedAuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public ManagedAuthenticatedEncryptorConfiguration() { } - public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type EncryptionAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ValidationAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type EncryptionAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ValidationAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class ManagedAuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -213,8 +213,8 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class XmlSerializedDescriptorInfo { public XmlSerializedDescriptorInfo(System.Xml.Linq.XElement serializedDescriptorElement, System.Type deserializerType) { } - public System.Type DeserializerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Xml.Linq.XElement SerializedDescriptorElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type DeserializerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Xml.Linq.XElement SerializedDescriptorElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.DataProtection.Internal @@ -251,13 +251,13 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement public partial class KeyManagementOptions { public KeyManagementOptions() { } - public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration AuthenticatedEncryptorConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList AuthenticatedEncryptorFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool AutoGenerateKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList KeyEscrowSinks { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration AuthenticatedEncryptorConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList AuthenticatedEncryptorFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool AutoGenerateKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList KeyEscrowSinks { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.TimeSpan NewKeyLifetime { get { throw null; } set { } } - public Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor XmlEncryptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository XmlRepository { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor XmlEncryptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository XmlRepository { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public sealed partial class XmlKeyManager : Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager, Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager { @@ -317,7 +317,7 @@ namespace Microsoft.AspNetCore.DataProtection.Repositories { public FileSystemXmlRepository(System.IO.DirectoryInfo directory, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public static System.IO.DirectoryInfo DefaultKeyStorageDirectory { get { throw null; } } - public System.IO.DirectoryInfo Directory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.IO.DirectoryInfo Directory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Collections.Generic.IReadOnlyCollection GetAllElements() { throw null; } public virtual void StoreElement(System.Xml.Linq.XElement element, string friendlyName) { } } @@ -330,7 +330,7 @@ namespace Microsoft.AspNetCore.DataProtection.Repositories { public RegistryXmlRepository(Microsoft.Win32.RegistryKey registryKey, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public static Microsoft.Win32.RegistryKey DefaultRegistryKey { get { throw null; } } - public Microsoft.Win32.RegistryKey RegistryKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Win32.RegistryKey RegistryKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Collections.Generic.IReadOnlyCollection GetAllElements() { throw null; } public virtual void StoreElement(System.Xml.Linq.XElement element, string friendlyName) { } } @@ -386,8 +386,8 @@ namespace Microsoft.AspNetCore.DataProtection.XmlEncryption public sealed partial class EncryptedXmlInfo { public EncryptedXmlInfo(System.Xml.Linq.XElement encryptedElement, System.Type decryptorType) { } - public System.Type DecryptorType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Xml.Linq.XElement EncryptedElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type DecryptorType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Xml.Linq.XElement EncryptedElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface ICertificateResolver { diff --git a/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netstandard2.0.cs b/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netstandard2.0.cs index 70cd9bfe67..87d5151d97 100644 --- a/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netstandard2.0.cs +++ b/src/DataProtection/DataProtection/ref/Microsoft.AspNetCore.DataProtection.netstandard2.0.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.DataProtection public partial class DataProtectionOptions { public DataProtectionOptions() { } - public string ApplicationDiscriminator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ApplicationDiscriminator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class DataProtectionUtilityExtensions { @@ -128,8 +128,8 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class AuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public AuthenticatedEncryptorConfiguration() { } - public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm ValidationAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm ValidationAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class AuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -145,11 +145,11 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class CngCbcAuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public CngCbcAuthenticatedEncryptorConfiguration() { } - public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HashAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HashAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HashAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HashAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class CngCbcAuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -165,9 +165,9 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class CngGcmAuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public CngGcmAuthenticatedEncryptorConfiguration() { } - public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string EncryptionAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EncryptionAlgorithmProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class CngGcmAuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -191,9 +191,9 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class ManagedAuthenticatedEncryptorConfiguration : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration { public ManagedAuthenticatedEncryptorConfiguration() { } - public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type EncryptionAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ValidationAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int EncryptionAlgorithmKeySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type EncryptionAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ValidationAlgorithmType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor CreateNewDescriptor() { throw null; } } public sealed partial class ManagedAuthenticatedEncryptorDescriptor : Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptor @@ -213,8 +213,8 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.Configurat public sealed partial class XmlSerializedDescriptorInfo { public XmlSerializedDescriptorInfo(System.Xml.Linq.XElement serializedDescriptorElement, System.Type deserializerType) { } - public System.Type DeserializerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Xml.Linq.XElement SerializedDescriptorElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type DeserializerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Xml.Linq.XElement SerializedDescriptorElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.DataProtection.Internal @@ -251,13 +251,13 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement public partial class KeyManagementOptions { public KeyManagementOptions() { } - public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration AuthenticatedEncryptorConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList AuthenticatedEncryptorFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool AutoGenerateKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList KeyEscrowSinks { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AlgorithmConfiguration AuthenticatedEncryptorConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList AuthenticatedEncryptorFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool AutoGenerateKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList KeyEscrowSinks { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.TimeSpan NewKeyLifetime { get { throw null; } set { } } - public Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor XmlEncryptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository XmlRepository { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.DataProtection.XmlEncryption.IXmlEncryptor XmlEncryptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository XmlRepository { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public sealed partial class XmlKeyManager : Microsoft.AspNetCore.DataProtection.KeyManagement.IKeyManager, Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager { @@ -317,7 +317,7 @@ namespace Microsoft.AspNetCore.DataProtection.Repositories { public FileSystemXmlRepository(System.IO.DirectoryInfo directory, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public static System.IO.DirectoryInfo DefaultKeyStorageDirectory { get { throw null; } } - public System.IO.DirectoryInfo Directory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.IO.DirectoryInfo Directory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Collections.Generic.IReadOnlyCollection GetAllElements() { throw null; } public virtual void StoreElement(System.Xml.Linq.XElement element, string friendlyName) { } } @@ -330,7 +330,7 @@ namespace Microsoft.AspNetCore.DataProtection.Repositories { public RegistryXmlRepository(Microsoft.Win32.RegistryKey registryKey, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public static Microsoft.Win32.RegistryKey DefaultRegistryKey { get { throw null; } } - public Microsoft.Win32.RegistryKey RegistryKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Win32.RegistryKey RegistryKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Collections.Generic.IReadOnlyCollection GetAllElements() { throw null; } public virtual void StoreElement(System.Xml.Linq.XElement element, string friendlyName) { } } @@ -386,8 +386,8 @@ namespace Microsoft.AspNetCore.DataProtection.XmlEncryption public sealed partial class EncryptedXmlInfo { public EncryptedXmlInfo(System.Xml.Linq.XElement encryptedElement, System.Type decryptorType) { } - public System.Type DecryptorType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Xml.Linq.XElement EncryptedElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type DecryptorType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Xml.Linq.XElement EncryptedElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface ICertificateResolver { diff --git a/src/DataProtection/DataProtection/src/AuthenticatedEncryption/IOptimizedAuthenticatedEncryptor.cs b/src/DataProtection/DataProtection/src/AuthenticatedEncryption/IOptimizedAuthenticatedEncryptor.cs index 3cc0a7ca92..9d28c11221 100644 --- a/src/DataProtection/DataProtection/src/AuthenticatedEncryption/IOptimizedAuthenticatedEncryptor.cs +++ b/src/DataProtection/DataProtection/src/AuthenticatedEncryption/IOptimizedAuthenticatedEncryptor.cs @@ -31,10 +31,10 @@ namespace Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption /// This method allows for a slight performance improvement over IAuthenticatedEncryptor.Encrypt /// in the case where the caller needs to prepend or append some data to the resulting ciphertext. /// For instance, if the caller needs to append a 32-bit header to the resulting ciphertext, then - /// he can specify 4 for 'preBufferSize' and overwrite the first 32 bits of the buffer returned + /// specify 4 for 'preBufferSize' and overwrite the first 32 bits of the buffer returned /// by this function. This saves the caller from having to allocate a new buffer to hold the final /// transformed result. - /// + /// /// All cryptography-related exceptions should be homogenized to CryptographicException. /// byte[] Encrypt(ArraySegment plaintext, ArraySegment additionalAuthenticatedData, uint preBufferSize, uint postBufferSize); diff --git a/src/DataProtection/DataProtection/src/IDataProtectionBuilder.cs b/src/DataProtection/DataProtection/src/IDataProtectionBuilder.cs index 95c7c61f50..68db854e74 100644 --- a/src/DataProtection/DataProtection/src/IDataProtectionBuilder.cs +++ b/src/DataProtection/DataProtection/src/IDataProtectionBuilder.cs @@ -15,14 +15,14 @@ namespace Microsoft.AspNetCore.DataProtection /// /// /// If the developer changes the at-rest key protection mechanism, it is intended that - /// he also change the key storage location, and vice versa. For instance, a call to + /// they also change the key storage location, and vice versa. For instance, a call to /// should generally be accompanied by /// a call to , or exceptions may /// occur at runtime due to the data protection system not knowing where to persist keys. /// /// /// Similarly, when a developer modifies the default protected payload cryptographic - /// algorithms, it is intended that he also select an explitiy key storage location. + /// algorithms, they should also set an explicit key storage location. /// A call to /// should therefore generally be paired with a call to , /// for example. @@ -40,4 +40,4 @@ namespace Microsoft.AspNetCore.DataProtection /// IServiceCollection Services { get; } } -} \ No newline at end of file +} diff --git a/src/DataProtection/DataProtection/src/KeyManagement/KeyRingBasedDataProtector.cs b/src/DataProtection/DataProtection/src/KeyManagement/KeyRingBasedDataProtector.cs index d1857d76d2..9fd73d6125 100644 --- a/src/DataProtection/DataProtection/src/KeyManagement/KeyRingBasedDataProtector.cs +++ b/src/DataProtection/DataProtection/src/KeyManagement/KeyRingBasedDataProtector.cs @@ -253,7 +253,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement } } - // Do we need to notify the caller that he should reprotect the data? + // Do we need to notify the caller that they should reprotect the data? status = UnprotectStatus.Ok; if (keyIdFromPayload != currentKeyRing.DefaultKeyId) { diff --git a/src/DataProtection/DataProtection/src/KeyManagement/KeyRingProvider.cs b/src/DataProtection/DataProtection/src/KeyManagement/KeyRingProvider.cs index 8f3fa1904d..ac180a31ed 100644 --- a/src/DataProtection/DataProtection/src/KeyManagement/KeyRingProvider.cs +++ b/src/DataProtection/DataProtection/src/KeyManagement/KeyRingProvider.cs @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement _defaultKeyResolver = defaultKeyResolver; _logger = loggerFactory.CreateLogger(); - // We will automatically refresh any unknown keys for 2 minutes see https://github.com/aspnet/AspNetCore/issues/3975 + // We will automatically refresh any unknown keys for 2 minutes see https://github.com/dotnet/aspnetcore/issues/3975 AutoRefreshWindowEnd = DateTime.UtcNow.AddMinutes(2); } @@ -226,9 +226,9 @@ namespace Microsoft.AspNetCore.DataProtection.KeyManagement Volatile.Write(ref _cacheableKeyRing, existingCacheableKeyRing.WithTemporaryExtendedLifetime(utcNow)); } - // The immediate caller should fail so that he can report the error up his chain. This makes it more likely + // The immediate caller should fail so that they can report the error up the chain. This makes it more likely // that an administrator can see the error and react to it as appropriate. The caller can retry the operation - // and will probably have success as long as he falls within the temporary extension mentioned above. + // and will probably have success as long as they fall within the temporary extension mentioned above. throw; } diff --git a/src/DataProtection/DataProtection/src/LoggingExtensions.cs b/src/DataProtection/DataProtection/src/LoggingExtensions.cs index 7792d48dbe..b54cd5659c 100644 --- a/src/DataProtection/DataProtection/src/LoggingExtensions.cs +++ b/src/DataProtection/DataProtection/src/LoggingExtensions.cs @@ -149,268 +149,268 @@ namespace Microsoft.Extensions.Logging static LoggingExtensions() { _usingFallbackKeyWithExpirationAsDefaultKey = LoggerMessage.Define( - eventId: 1, + eventId: new EventId(1, "UsingFallbackKeyWithExpirationAsDefaultKey"), logLevel: LogLevel.Warning, formatString: "Policy resolution states that a new key should be added to the key ring, but automatic generation of keys is disabled. Using fallback key {KeyId:B} with expiration {ExpirationDate:u} as default key."); _usingKeyAsDefaultKey = LoggerMessage.Define( - eventId: 2, + eventId: new EventId(2, "UsingKeyAsDefaultKey"), logLevel: LogLevel.Debug, formatString: "Using key {KeyId:B} as the default key."); _openingCNGAlgorithmFromProviderWithHMAC = LoggerMessage.Define( - eventId: 3, + eventId: new EventId(3, "OpeningCNGAlgorithmFromProviderWithHMAC"), logLevel: LogLevel.Debug, formatString: "Opening CNG algorithm '{HashAlgorithm}' from provider '{HashAlgorithmProvider}' with HMAC."); _openingCNGAlgorithmFromProviderWithChainingModeCBC = LoggerMessage.Define( - eventId: 4, + eventId: new EventId(4, "OpeningCNGAlgorithmFromProviderWithChainingModeCBC"), logLevel: LogLevel.Debug, formatString: "Opening CNG algorithm '{EncryptionAlgorithm}' from provider '{EncryptionAlgorithmProvider}' with chaining mode CBC."); _performingUnprotectOperationToKeyWithPurposes = LoggerMessage.Define( - eventId: 5, + eventId: new EventId(5, "PerformingUnprotectOperationToKeyWithPurposes"), logLevel: LogLevel.Trace, formatString: "Performing unprotect operation to key {KeyId:B} with purposes {Purposes}."); _keyWasNotFoundInTheKeyRingUnprotectOperationCannotProceed = LoggerMessage.Define( - eventId: 6, + eventId: new EventId(6, "KeyWasNotFoundInTheKeyRingUnprotectOperationCannotProceed"), logLevel: LogLevel.Trace, formatString: "Key {KeyId:B} was not found in the key ring. Unprotect operation cannot proceed."); _keyWasRevokedCallerRequestedUnprotectOperationProceedRegardless = LoggerMessage.Define( - eventId: 7, + eventId: new EventId(7, "KeyWasRevokedCallerRequestedUnprotectOperationProceedRegardless"), logLevel: LogLevel.Debug, formatString: "Key {KeyId:B} was revoked. Caller requested unprotect operation proceed regardless."); _keyWasRevokedUnprotectOperationCannotProceed = LoggerMessage.Define( - eventId: 8, + eventId: new EventId(8, "KeyWasRevokedUnprotectOperationCannotProceed"), logLevel: LogLevel.Debug, formatString: "Key {KeyId:B} was revoked. Unprotect operation cannot proceed."); _openingCNGAlgorithmFromProviderWithChainingModeGCM = LoggerMessage.Define( - eventId: 9, + eventId: new EventId(9, "OpeningCNGAlgorithmFromProviderWithChainingModeGCM"), logLevel: LogLevel.Debug, formatString: "Opening CNG algorithm '{EncryptionAlgorithm}' from provider '{EncryptionAlgorithmProvider}' with chaining mode GCM."); _usingManagedKeyedHashAlgorithm = LoggerMessage.Define( - eventId: 10, + eventId: new EventId(10, "UsingManagedKeyedHashAlgorithm"), logLevel: LogLevel.Debug, formatString: "Using managed keyed hash algorithm '{FullName}'."); _usingManagedSymmetricAlgorithm = LoggerMessage.Define( - eventId: 11, + eventId: new EventId(11, "UsingManagedSymmetricAlgorithm"), logLevel: LogLevel.Debug, formatString: "Using managed symmetric algorithm '{FullName}'."); _keyIsIneligibleToBeTheDefaultKeyBecauseItsMethodFailed = LoggerMessage.Define( - eventId: 12, + eventId: new EventId(12, "KeyIsIneligibleToBeTheDefaultKeyBecauseItsMethodFailed"), logLevel: LogLevel.Warning, formatString: "Key {KeyId:B} is ineligible to be the default key because its {MethodName} method failed."); _consideringKeyWithExpirationDateAsDefaultKey = LoggerMessage.Define( - eventId: 13, + eventId: new EventId(13, "ConsideringKeyWithExpirationDateAsDefaultKey"), logLevel: LogLevel.Debug, formatString: "Considering key {KeyId:B} with expiration date {ExpirationDate:u} as default key."); _keyIsNoLongerUnderConsiderationAsDefault = LoggerMessage.Define( - eventId: 14, + eventId: new EventId(14, "KeyIsNoLongerUnderConsiderationAsDefault"), logLevel: LogLevel.Debug, formatString: "Key {KeyId:B} is no longer under consideration as default key because it is expired, revoked, or cannot be deciphered."); _unknownElementWithNameFoundInKeyringSkipping = LoggerMessage.Define( - eventId: 15, + eventId: new EventId(15, "UnknownElementWithNameFoundInKeyringSkipping"), logLevel: LogLevel.Warning, formatString: "Unknown element with name '{Name}' found in keyring, skipping."); _markedKeyAsRevokedInTheKeyring = LoggerMessage.Define( - eventId: 16, + eventId: new EventId(16, "MarkedKeyAsRevokedInTheKeyring"), logLevel: LogLevel.Debug, formatString: "Marked key {KeyId:B} as revoked in the keyring."); _triedToProcessRevocationOfKeyButNoSuchKeyWasFound = LoggerMessage.Define( - eventId: 17, + eventId: new EventId(17, "TriedToProcessRevocationOfKeyButNoSuchKeyWasFound"), logLevel: LogLevel.Warning, formatString: "Tried to process revocation of key {KeyId:B}, but no such key was found in keyring. Skipping."); _foundKey = LoggerMessage.Define( - eventId: 18, + eventId: new EventId(18, "FoundKey"), logLevel: LogLevel.Debug, formatString: "Found key {KeyId:B}."); _foundRevocationOfAllKeysCreatedPriorTo = LoggerMessage.Define( - eventId: 19, + eventId: new EventId(19, "FoundRevocationOfAllKeysCreatedPriorTo"), logLevel: LogLevel.Debug, formatString: "Found revocation of all keys created prior to {RevocationDate:u}."); _foundRevocationOfKey = LoggerMessage.Define( - eventId: 20, + eventId: new EventId(20, "FoundRevocationOfKey"), logLevel: LogLevel.Debug, formatString: "Found revocation of key {KeyId:B}."); _exceptionWhileProcessingRevocationElement = LoggerMessage.Define( - eventId: 21, + eventId: new EventId(21, "ExceptionWhileProcessingRevocationElement"), logLevel: LogLevel.Error, formatString: "An exception occurred while processing the revocation element '{RevocationElement}'. Cannot continue keyring processing."); _revokingAllKeysAsOfForReason = LoggerMessage.Define( - eventId: 22, + eventId: new EventId(22, "RevokingAllKeysAsOfForReason"), logLevel: LogLevel.Information, formatString: "Revoking all keys as of {RevocationDate:u} for reason '{Reason}'."); _keyCacheExpirationTokenTriggeredByOperation = LoggerMessage.Define( - eventId: 23, + eventId: new EventId(23, "KeyCacheExpirationTokenTriggeredByOperation"), logLevel: LogLevel.Debug, formatString: "Key cache expiration token triggered by '{OperationName}' operation."); _anExceptionOccurredWhileProcessingTheKeyElement = LoggerMessage.Define( - eventId: 24, + eventId: new EventId(24, "ExceptionOccurredWhileProcessingTheKeyElement"), logLevel: LogLevel.Error, formatString: "An exception occurred while processing the key element '{Element}'."); _anExceptionOccurredWhileProcessingTheKeyElementDebug = LoggerMessage.Define( - eventId: 25, + eventId: new EventId(25, "ExceptionOccurredWhileProcessingTheKeyElementDebug"), logLevel: LogLevel.Trace, formatString: "An exception occurred while processing the key element '{Element}'."); _encryptingToWindowsDPAPIForCurrentUserAccount = LoggerMessage.Define( - eventId: 26, + eventId: new EventId(26, "EncryptingToWindowsDPAPIForCurrentUserAccount"), logLevel: LogLevel.Debug, formatString: "Encrypting to Windows DPAPI for current user account ({Name})."); _encryptingToWindowsDPAPINGUsingProtectionDescriptorRule = LoggerMessage.Define( - eventId: 27, + eventId: new EventId(27, "EncryptingToWindowsDPAPINGUsingProtectionDescriptorRule"), logLevel: LogLevel.Debug, formatString: "Encrypting to Windows DPAPI-NG using protection descriptor rule '{DescriptorRule}'."); _anErrorOccurredWhileEncryptingToX509CertificateWithThumbprint = LoggerMessage.Define( - eventId: 28, + eventId: new EventId(28, "ErrorOccurredWhileEncryptingToX509CertificateWithThumbprint"), logLevel: LogLevel.Error, formatString: "An error occurred while encrypting to X.509 certificate with thumbprint '{Thumbprint}'."); _encryptingToX509CertificateWithThumbprint = LoggerMessage.Define( - eventId: 29, + eventId: new EventId(29, "EncryptingToX509CertificateWithThumbprint"), logLevel: LogLevel.Debug, formatString: "Encrypting to X.509 certificate with thumbprint '{Thumbprint}'."); _exceptionOccurredWhileTryingToResolveCertificateWithThumbprint = LoggerMessage.Define( - eventId: 30, + eventId: new EventId(30, "ExceptionOccurredWhileTryingToResolveCertificateWithThumbprint"), logLevel: LogLevel.Error, formatString: "An exception occurred while trying to resolve certificate with thumbprint '{Thumbprint}'."); _performingProtectOperationToKeyWithPurposes = LoggerMessage.Define( - eventId: 31, + eventId: new EventId(31, "PerformingProtectOperationToKeyWithPurposes"), logLevel: LogLevel.Trace, formatString: "Performing protect operation to key {KeyId:B} with purposes {Purposes}."); _descriptorDeserializerTypeForKeyIs = LoggerMessage.Define( - eventId: 32, + eventId: new EventId(32, "DescriptorDeserializerTypeForKeyIs"), logLevel: LogLevel.Debug, formatString: "Descriptor deserializer type for key {KeyId:B} is '{AssemblyQualifiedName}'."); _keyEscrowSinkFoundWritingKeyToEscrow = LoggerMessage.Define( - eventId: 33, + eventId: new EventId(33, "KeyEscrowSinkFoundWritingKeyToEscrow"), logLevel: LogLevel.Debug, formatString: "Key escrow sink found. Writing key {KeyId:B} to escrow."); _noKeyEscrowSinkFoundNotWritingKeyToEscrow = LoggerMessage.Define( - eventId: 34, + eventId: new EventId(34, "NoKeyEscrowSinkFoundNotWritingKeyToEscrow"), logLevel: LogLevel.Debug, formatString: "No key escrow sink found. Not writing key {KeyId:B} to escrow."); _noXMLEncryptorConfiguredKeyMayBePersistedToStorageInUnencryptedForm = LoggerMessage.Define( - eventId: 35, + eventId: new EventId(35, "NoXMLEncryptorConfiguredKeyMayBePersistedToStorageInUnencryptedForm"), logLevel: LogLevel.Warning, formatString: "No XML encryptor configured. Key {KeyId:B} may be persisted to storage in unencrypted form."); _revokingKeyForReason = LoggerMessage.Define( - eventId: 36, + eventId: new EventId(36, "RevokingKeyForReason"), logLevel: LogLevel.Information, formatString: "Revoking key {KeyId:B} at {RevocationDate:u} for reason '{Reason}'."); _readingDataFromFile = LoggerMessage.Define( - eventId: 37, + eventId: new EventId(37, "ReadingDataFromFile"), logLevel: LogLevel.Debug, formatString: "Reading data from file '{FullPath}'."); _nameIsNotSafeFileName = LoggerMessage.Define( - eventId: 38, + eventId: new EventId(38, "NameIsNotSafeFileName"), logLevel: LogLevel.Debug, formatString: "The name '{FriendlyName}' is not a safe file name, using '{NewFriendlyName}' instead."); _writingDataToFile = LoggerMessage.Define( - eventId: 39, + eventId: new EventId(39, "WritingDataToFile"), logLevel: LogLevel.Information, formatString: "Writing data to file '{FileName}'."); _readingDataFromRegistryKeyValue = LoggerMessage.Define( - eventId: 40, + eventId: new EventId(40, "ReadingDataFromRegistryKeyValue"), logLevel: LogLevel.Debug, formatString: "Reading data from registry key '{RegistryKeyName}', value '{Value}'."); _nameIsNotSafeRegistryValueName = LoggerMessage.Define( - eventId: 41, + eventId: new EventId(41, "NameIsNotSafeRegistryValueName"), logLevel: LogLevel.Debug, formatString: "The name '{FriendlyName}' is not a safe registry value name, using '{NewFriendlyName}' instead."); _decryptingSecretElementUsingWindowsDPAPING = LoggerMessage.Define( - eventId: 42, + eventId: new EventId(42, "DecryptingSecretElementUsingWindowsDPAPING"), logLevel: LogLevel.Debug, formatString: "Decrypting secret element using Windows DPAPI-NG with protection descriptor rule '{DescriptorRule}'."); _exceptionOccurredTryingToDecryptElement = LoggerMessage.Define( - eventId: 43, + eventId: new EventId(43, "ExceptionOccurredTryingToDecryptElement"), logLevel: LogLevel.Error, formatString: "An exception occurred while trying to decrypt the element."); _encryptingUsingNullEncryptor = LoggerMessage.Define( - eventId: 44, + eventId: new EventId(44, "EncryptingUsingNullEncryptor"), logLevel: LogLevel.Warning, formatString: "Encrypting using a null encryptor; secret information isn't being protected."); _usingEphemeralDataProtectionProvider = LoggerMessage.Define( - eventId: 45, + eventId: new EventId(45, "UsingEphemeralDataProtectionProvider"), logLevel: LogLevel.Warning, formatString: "Using ephemeral data protection provider. Payloads will be undecipherable upon application shutdown."); _existingCachedKeyRingIsExpiredRefreshing = LoggerMessage.Define( - eventId: 46, + eventId: new EventId(46, "ExistingCachedKeyRingIsExpiredRefreshing"), logLevel: LogLevel.Debug, formatString: "Existing cached key ring is expired. Refreshing."); _errorOccurredWhileRefreshingKeyRing = LoggerMessage.Define( - eventId: 47, + eventId: new EventId(47, "ErrorOccurredWhileRefreshingKeyRing"), logLevel: LogLevel.Error, formatString: "An error occurred while refreshing the key ring. Will try again in 2 minutes."); _errorOccurredWhileReadingKeyRing = LoggerMessage.Define( - eventId: 48, + eventId: new EventId(48, "ErrorOccurredWhileReadingKeyRing"), logLevel: LogLevel.Error, formatString: "An error occurred while reading the key ring."); _keyRingDoesNotContainValidDefaultKey = LoggerMessage.Define( - eventId: 49, + eventId: new EventId(49, "KeyRingDoesNotContainValidDefaultKey"), logLevel: LogLevel.Error, formatString: "The key ring does not contain a valid default key, and the key manager is configured with auto-generation of keys disabled."); _usingInmemoryRepository = LoggerMessage.Define( - eventId: 50, + eventId: new EventId(50, "UsingInMemoryRepository"), logLevel: LogLevel.Warning, formatString: "Using an in-memory repository. Keys will not be persisted to storage."); _decryptingSecretElementUsingWindowsDPAPI = LoggerMessage.Define( - eventId: 51, + eventId: new EventId(51, "DecryptingSecretElementUsingWindowsDPAPI"), logLevel: LogLevel.Debug, formatString: "Decrypting secret element using Windows DPAPI."); _defaultKeyExpirationImminentAndRepository = LoggerMessage.Define( - eventId: 52, + eventId: new EventId(52, "DefaultKeyExpirationImminentAndRepository"), logLevel: LogLevel.Debug, formatString: "Default key expiration imminent and repository contains no viable successor. Caller should generate a successor."); _repositoryContainsNoViableDefaultKey = LoggerMessage.Define( - eventId: 53, + eventId: new EventId(53, "RepositoryContainsNoViableDefaultKey"), logLevel: LogLevel.Debug, formatString: "Repository contains no viable default key. Caller should generate a key with immediate activation."); _errorOccurredWhileEncryptingToWindowsDPAPI = LoggerMessage.Define( - eventId: 54, + eventId: new EventId(54, "ErrorOccurredWhileEncryptingToWindowsDPAPI"), logLevel: LogLevel.Error, formatString: "An error occurred while encrypting to Windows DPAPI."); _encryptingToWindowsDPAPIForLocalMachineAccount = LoggerMessage.Define( - eventId: 55, + eventId: new EventId(55, "EncryptingToWindowsDPAPIForLocalMachineAccount"), logLevel: LogLevel.Debug, formatString: "Encrypting to Windows DPAPI for local machine account."); _errorOccurredWhileEncryptingToWindowsDPAPING = LoggerMessage.Define( - eventId: 56, + eventId: new EventId(56, "ErrorOccurredWhileEncryptingToWindowsDPAPING"), logLevel: LogLevel.Error, formatString: "An error occurred while encrypting to Windows DPAPI-NG."); _policyResolutionStatesThatANewKeyShouldBeAddedToTheKeyRing = LoggerMessage.Define( - eventId: 57, + eventId: new EventId(57, "PolicyResolutionStatesThatANewKeyShouldBeAddedToTheKeyRing"), logLevel: LogLevel.Debug, formatString: "Policy resolution states that a new key should be added to the key ring."); _creatingKey = LoggerMessage.Define( - eventId: 58, + eventId: new EventId(58, "CreatingKey"), logLevel: LogLevel.Information, formatString: "Creating key {KeyId:B} with creation date {CreationDate:u}, activation date {ActivationDate:u}, and expiration date {ExpirationDate:u}."); _usingEphemeralKeyRepository = LoggerMessage.Define( - eventId: 59, + eventId: new EventId(59, "UsingEphemeralKeyRepository"), logLevel: LogLevel.Warning, formatString: "Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits."); _usingEphemeralFileSystemLocationInContainer = LoggerMessage.Define( - eventId: 60, + eventId: new EventId(60, "UsingEphemeralFileSystemLocationInContainer"), logLevel: LogLevel.Warning, formatString: Resources.FileSystem_EphemeralKeysLocationInContainer); _usingRegistryAsKeyRepositoryWithDPAPI = LoggerMessage.Define( - eventId: 0, + eventId: new EventId(61, "UsingRegistryAsKeyRepositoryWithDPAPI"), logLevel: LogLevel.Information, formatString: "User profile not available. Using '{Name}' as key repository and Windows DPAPI to encrypt keys at rest."); _usingProfileAsKeyRepository = LoggerMessage.Define( - eventId: 0, + eventId: new EventId(62, "UsingProfileAsKeyRepository"), logLevel: LogLevel.Information, formatString: "User profile is available. Using '{FullName}' as key repository; keys will not be encrypted at rest."); _usingProfileAsKeyRepositoryWithDPAPI = LoggerMessage.Define( - eventId: 0, + eventId: new EventId(63, "UsingProfileAsKeyRepositoryWithDPAPI"), logLevel: LogLevel.Information, formatString: "User profile is available. Using '{FullName}' as key repository and Windows DPAPI to encrypt keys at rest."); _usingAzureAsKeyRepository = LoggerMessage.Define( - eventId: 0, + eventId: new EventId(64, "UsingAzureAsKeyRepository"), logLevel: LogLevel.Information, formatString: "Azure Web Sites environment detected. Using '{FullName}' as key repository; keys will not be encrypted at rest."); _keyRingWasLoadedOnStartup = LoggerMessage.Define( - eventId: 0, + eventId: new EventId(65, "KeyRingWasLoadedOnStartup"), logLevel: LogLevel.Debug, formatString: "Key ring with default key {KeyId:B} was loaded during application startup."); _keyRingFailedToLoadOnStartup = LoggerMessage.Define( - eventId: 0, + eventId: new EventId(66, "KeyRingFailedToLoadOnStartup"), logLevel: LogLevel.Information, formatString: "Key ring failed to load during application startup."); } diff --git a/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs b/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs index d334f36672..1a96268960 100644 --- a/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs +++ b/src/DataProtection/DataProtection/src/Managed/ManagedGenRandomImpl.cs @@ -8,7 +8,9 @@ namespace Microsoft.AspNetCore.DataProtection.Managed { internal unsafe sealed class ManagedGenRandomImpl : IManagedGenRandom { +#if NETSTANDARD2_0 private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); +#endif public static readonly ManagedGenRandomImpl Instance = new ManagedGenRandomImpl(); private ManagedGenRandomImpl() @@ -18,7 +20,11 @@ namespace Microsoft.AspNetCore.DataProtection.Managed public byte[] GenRandom(int numBytes) { var bytes = new byte[numBytes]; +#if NETSTANDARD2_0 _rng.GetBytes(bytes); +#else + RandomNumberGenerator.Fill(bytes); +#endif return bytes; } } diff --git a/src/DataProtection/DataProtection/src/Repositories/FileSystemXmlRepository.cs b/src/DataProtection/DataProtection/src/Repositories/FileSystemXmlRepository.cs index 19e11b6ac9..12785c943d 100644 --- a/src/DataProtection/DataProtection/src/Repositories/FileSystemXmlRepository.cs +++ b/src/DataProtection/DataProtection/src/Repositories/FileSystemXmlRepository.cs @@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.DataProtection.Repositories } catch (Exception ex) { - // Treat exceptions as non-fatal when attempting to detect docker. + // Treat exceptions as non-fatal when attempting to detect docker. // These might occur if fstab is an unrecognized format, or if there are other unusual // file IO errors. _logger.LogTrace(ex, "Failure occurred while attempting to detect docker."); @@ -151,7 +151,7 @@ namespace Microsoft.AspNetCore.DataProtection.Repositories catch (IOException) { // Use File.Copy because File.Move on NFS shares has issues in .NET Core 2.0 - // See https://github.com/aspnet/AspNetCore/issues/2941 for more context + // See https://github.com/dotnet/aspnetcore/issues/2941 for more context File.Copy(tempFilename, finalFilename); } } diff --git a/src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs b/src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs index 6c4ae69807..67ab1ae859 100644 --- a/src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs +++ b/src/DataProtection/EntityFrameworkCore/ref/Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.netstandard2.1.cs @@ -13,9 +13,9 @@ namespace Microsoft.AspNetCore.DataProtection.EntityFrameworkCore public partial class DataProtectionKey { public DataProtectionKey() { } - public string FriendlyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Xml { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FriendlyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Xml { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class EntityFrameworkCoreXmlRepository : Microsoft.AspNetCore.DataProtection.Repositories.IXmlRepository where TContext : Microsoft.EntityFrameworkCore.DbContext, Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.IDataProtectionKeyContext { diff --git a/src/DataProtection/EntityFrameworkCore/src/LoggingExtensions.cs b/src/DataProtection/EntityFrameworkCore/src/LoggingExtensions.cs index d0aeb09271..193c0100ac 100644 --- a/src/DataProtection/EntityFrameworkCore/src/LoggingExtensions.cs +++ b/src/DataProtection/EntityFrameworkCore/src/LoggingExtensions.cs @@ -13,11 +13,11 @@ namespace Microsoft.Extensions.Logging static LoggingExtensions() { _anExceptionOccurredWhileParsingKeyXml = LoggerMessage.Define( - eventId: 1, + eventId: new EventId(1, "ExceptionOccurredWhileParsingKeyXml"), logLevel: LogLevel.Warning, formatString: "An exception occurred while parsing the key xml '{Xml}'."); _savingKeyToDbContext = LoggerMessage.Define( - eventId: 2, + eventId: new EventId(2, "SavingKeyToDbContext"), logLevel: LogLevel.Debug, formatString: "Saving key '{FriendlyName}' to '{DbContext}'."); } diff --git a/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs b/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs index 965f472d28..5caee24b12 100644 --- a/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs +++ b/src/DataProtection/Extensions/test/DataProtectionProviderTests.cs @@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.DataProtection [ConditionalFact] [X509StoreIsAvailable(StoreName.My, StoreLocation.CurrentUser)] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public void System_UsesProvidedDirectoryAndCertificate() { var filePath = Path.Combine(GetTestFilesPath(), "TestCert.pfx"); @@ -165,7 +165,7 @@ namespace Microsoft.AspNetCore.DataProtection [ConditionalFact] [X509StoreIsAvailable(StoreName.My, StoreLocation.CurrentUser)] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public void System_UsesProvidedCertificateNotFromStore() { using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) diff --git a/src/DataProtection/README.md b/src/DataProtection/README.md index cd58074d9e..4c558753b0 100644 --- a/src/DataProtection/README.md +++ b/src/DataProtection/README.md @@ -1,7 +1,7 @@ DataProtection ============== -Data Protection APIs for protecting and unprotecting data. You can find documentation for Data Protection in the [ASP.NET Core Documentation](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/). +Data Protection APIs for protecting and unprotecting data. You can find documentation for Data Protection in the [ASP.NET Core Documentation](https://docs.microsoft.com/aspnet/core/security/data-protection/). ## Community Maintained Data Protection Providers & Projects diff --git a/src/DataProtection/samples/EntityFrameworkCoreSample/EntityFrameworkCoreSample.csproj b/src/DataProtection/samples/EntityFrameworkCoreSample/EntityFrameworkCoreSample.csproj index 6c161137a5..c1b2662b90 100644 --- a/src/DataProtection/samples/EntityFrameworkCoreSample/EntityFrameworkCoreSample.csproj +++ b/src/DataProtection/samples/EntityFrameworkCoreSample/EntityFrameworkCoreSample.csproj @@ -3,6 +3,9 @@ exe $(DefaultNetCoreTargetFramework) + + $(NoWarn);NU1605 diff --git a/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj b/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj index 41aee06e07..db9481cd58 100644 --- a/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj +++ b/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/Microsoft.AspNetCore.FunctionalTests.csproj @@ -4,7 +4,7 @@ $(DefaultNetCoreTargetFramework) - + false diff --git a/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs b/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs index 79ef5dfc33..da51bb4a3c 100644 --- a/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs +++ b/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs @@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.Tests var applicationName = "CreateDefaultBuilderApp"; var deploymentParameters = new DeploymentParameters(Path.Combine(GetTestSitesPath(), applicationName), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { - TargetFramework = "netcoreapp3.1", + TargetFramework = "netcoreapp5.0", HostingModel = HostingModel.InProcess }; @@ -213,7 +213,7 @@ namespace Microsoft.AspNetCore.Tests { var deploymentParameters = new DeploymentParameters(Path.Combine(GetTestSitesPath(), applicationName), ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64) { - TargetFramework = "netcoreapp3.1", + TargetFramework = "netcoreapp5.0", }; if (setTestEnvVars) diff --git a/src/Features/JsonPatch/JsonPatch.sln b/src/Features/JsonPatch/JsonPatch.sln new file mode 100644 index 0000000000..efa5fbdf86 --- /dev/null +++ b/src/Features/JsonPatch/JsonPatch.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.JsonPatch", "src\Microsoft.AspNetCore.JsonPatch.csproj", "{B2094419-9ED4-4733-B15D-60314118B61C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.JsonPatch.Tests", "test\Microsoft.AspNetCore.JsonPatch.Tests.csproj", "{4F34177F-6E1E-4880-A2CA-0511EFEDB395}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B2094419-9ED4-4733-B15D-60314118B61C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Debug|x64.ActiveCfg = Debug|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Debug|x64.Build.0 = Debug|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Debug|x86.ActiveCfg = Debug|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Debug|x86.Build.0 = Debug|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Release|Any CPU.Build.0 = Release|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Release|x64.ActiveCfg = Release|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Release|x64.Build.0 = Release|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Release|x86.ActiveCfg = Release|Any CPU + {B2094419-9ED4-4733-B15D-60314118B61C}.Release|x86.Build.0 = Release|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Debug|x64.ActiveCfg = Debug|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Debug|x64.Build.0 = Debug|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Debug|x86.ActiveCfg = Debug|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Debug|x86.Build.0 = Debug|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Release|Any CPU.Build.0 = Release|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Release|x64.ActiveCfg = Release|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Release|x64.Build.0 = Release|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Release|x86.ActiveCfg = Release|Any CPU + {4F34177F-6E1E-4880-A2CA-0511EFEDB395}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/Features/JsonPatch/ref/Microsoft.AspNetCore.JsonPatch.netstandard2.0.cs b/src/Features/JsonPatch/ref/Microsoft.AspNetCore.JsonPatch.netstandard2.0.cs index f8ba24f51f..61ba9315d9 100644 --- a/src/Features/JsonPatch/ref/Microsoft.AspNetCore.JsonPatch.netstandard2.0.cs +++ b/src/Features/JsonPatch/ref/Microsoft.AspNetCore.JsonPatch.netstandard2.0.cs @@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.JsonPatch public JsonPatchDocument() { } public JsonPatchDocument(System.Collections.Generic.List operations, Newtonsoft.Json.Serialization.IContractResolver contractResolver) { } [Newtonsoft.Json.JsonIgnoreAttribute] - public Newtonsoft.Json.Serialization.IContractResolver ContractResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.List Operations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Newtonsoft.Json.Serialization.IContractResolver ContractResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.List Operations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.JsonPatch.JsonPatchDocument Add(string path, object value) { throw null; } public void ApplyTo(object objectToApplyTo) { } public void ApplyTo(object objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter) { } @@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.JsonPatch public JsonPatchDocument() { } public JsonPatchDocument(System.Collections.Generic.List> operations, Newtonsoft.Json.Serialization.IContractResolver contractResolver) { } [Newtonsoft.Json.JsonIgnoreAttribute] - public Newtonsoft.Json.Serialization.IContractResolver ContractResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.List> Operations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Newtonsoft.Json.Serialization.IContractResolver ContractResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.List> Operations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.JsonPatch.JsonPatchDocument Add(System.Linq.Expressions.Expression>> path, TProp value) { throw null; } public Microsoft.AspNetCore.JsonPatch.JsonPatchDocument Add(System.Linq.Expressions.Expression>> path, TProp value, int position) { throw null; } public Microsoft.AspNetCore.JsonPatch.JsonPatchDocument Add(System.Linq.Expressions.Expression> path, TProp value) { throw null; } @@ -69,15 +69,15 @@ namespace Microsoft.AspNetCore.JsonPatch public partial class JsonPatchError { public JsonPatchError(object affectedObject, Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, string errorMessage) { } - public object AffectedObject { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.JsonPatch.Operations.Operation Operation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object AffectedObject { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.JsonPatch.Operations.Operation Operation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class JsonPatchProperty { public JsonPatchProperty(Newtonsoft.Json.Serialization.JsonProperty property, object parent) { } - public object Parent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Newtonsoft.Json.Serialization.JsonProperty Property { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Parent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Newtonsoft.Json.Serialization.JsonProperty Property { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.JsonPatch.Adapters @@ -107,9 +107,9 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters { public ObjectAdapter(Newtonsoft.Json.Serialization.IContractResolver contractResolver, System.Action logErrorAction) { } public ObjectAdapter(Newtonsoft.Json.Serialization.IContractResolver contractResolver, System.Action logErrorAction, Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory adapterFactory) { } - public Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory AdapterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Newtonsoft.Json.Serialization.IContractResolver ContractResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Action LogErrorAction { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.JsonPatch.Adapters.IAdapterFactory AdapterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Newtonsoft.Json.Serialization.IContractResolver ContractResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Action LogErrorAction { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Add(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) { } public void Copy(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) { } public void Move(Microsoft.AspNetCore.JsonPatch.Operations.Operation operation, object objectToApplyTo) { } @@ -141,8 +141,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Exceptions public JsonPatchException(Microsoft.AspNetCore.JsonPatch.JsonPatchError jsonPatchError) { } public JsonPatchException(Microsoft.AspNetCore.JsonPatch.JsonPatchError jsonPatchError, System.Exception innerException) { } public JsonPatchException(string message, System.Exception innerException) { } - public object AffectedObject { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.JsonPatch.Operations.Operation FailedOperation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object AffectedObject { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.JsonPatch.Operations.Operation FailedOperation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.JsonPatch.Helpers @@ -150,8 +150,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers public partial class GetValueResult { public GetValueResult(object propertyValue, bool hasError) { } - public bool HasError { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object PropertyValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool HasError { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object PropertyValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.JsonPatch.Internal @@ -159,8 +159,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public partial class ConversionResult { public ConversionResult(bool canBeConverted, object convertedInstance) { } - public bool CanBeConverted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object ConvertedInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool CanBeConverted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object ConvertedInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class ConversionResultProvider { @@ -201,6 +201,16 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal bool TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage); bool TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object nextTarget, out string errorMessage); } + public partial class JObjectAdapter : Microsoft.AspNetCore.JsonPatch.Internal.IAdapter + { + public JObjectAdapter() { } + public virtual bool TryAdd(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) { throw null; } + public virtual bool TryGet(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object value, out string errorMessage) { throw null; } + public virtual bool TryRemove(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out string errorMessage) { throw null; } + public virtual bool TryReplace(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) { throw null; } + public virtual bool TryTest(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, object value, out string errorMessage) { throw null; } + public virtual bool TryTraverse(object target, string segment, Newtonsoft.Json.Serialization.IContractResolver contractResolver, out object nextTarget, out string errorMessage) { throw null; } + } public partial class ListAdapter : Microsoft.AspNetCore.JsonPatch.Internal.IAdapter { public ListAdapter() { } @@ -225,8 +235,8 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal { private readonly int _dummyPrimitive; public PositionInfo(Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType type, int index) { throw null; } - public int Index { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int Index { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.JsonPatch.Internal.ListAdapter.PositionType Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } protected enum PositionType { @@ -246,6 +256,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Internal public readonly partial struct ParsedPath { private readonly object _dummy; + private readonly int _dummyPrimitive; public ParsedPath(string path) { throw null; } public string LastSegment { get { throw null; } } public System.Collections.Generic.IReadOnlyList Segments { get { throw null; } } @@ -271,7 +282,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations public Operation(string op, string path, string from) { } public Operation(string op, string path, string from, object value) { } [Newtonsoft.Json.JsonPropertyAttribute("value")] - public object value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Apply(object objectToApplyTo, Microsoft.AspNetCore.JsonPatch.Adapters.IObjectAdapter adapter) { } public bool ShouldSerializevalue() { throw null; } } @@ -280,13 +291,13 @@ namespace Microsoft.AspNetCore.JsonPatch.Operations public OperationBase() { } public OperationBase(string op, string path, string from) { } [Newtonsoft.Json.JsonPropertyAttribute("from")] - public string from { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string from { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Newtonsoft.Json.JsonPropertyAttribute("op")] public string op { get { throw null; } set { } } [Newtonsoft.Json.JsonIgnoreAttribute] public Microsoft.AspNetCore.JsonPatch.Operations.OperationType OperationType { get { throw null; } } [Newtonsoft.Json.JsonPropertyAttribute("path")] - public string path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool ShouldSerializefrom() { throw null; } } public enum OperationType diff --git a/src/Features/JsonPatch/src/Adapters/AdapterFactory.cs b/src/Features/JsonPatch/src/Adapters/AdapterFactory.cs index 078f83e175..ff91018a88 100644 --- a/src/Features/JsonPatch/src/Adapters/AdapterFactory.cs +++ b/src/Features/JsonPatch/src/Adapters/AdapterFactory.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.JsonPatch.Internal; +using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using System; using System.Collections; @@ -29,6 +30,10 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters var jsonContract = contractResolver.ResolveContract(target.GetType()); + if (target is JObject) + { + return new JObjectAdapter(); + } if (target is IList) { return new ListAdapter(); diff --git a/src/Features/JsonPatch/src/Adapters/IObjectAdapter.cs b/src/Features/JsonPatch/src/Adapters/IObjectAdapter.cs index e5206bfa0d..0c15ce0ae6 100644 --- a/src/Features/JsonPatch/src/Adapters/IObjectAdapter.cs +++ b/src/Features/JsonPatch/src/Adapters/IObjectAdapter.cs @@ -7,18 +7,18 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters { /// /// Defines the operations that can be performed on a JSON patch document. - /// + /// public interface IObjectAdapter { /// /// Using the "add" operation a new value is inserted into the root of the target /// document, into the target array at the specified valid index, or to a target object at /// the specified location. - /// - /// When adding to arrays, the specified index MUST NOT be greater than the number of elements in the array. + /// + /// When adding to arrays, the specified index MUST NOT be greater than the number of elements in the array. /// To append the value to the array, the index of "-" character is used (see [RFC6901]). - /// - /// When adding to an object, if an object member does not already exist, a new member is added to the object at the + /// + /// When adding to an object, if an object member does not already exist, a new member is added to the object at the /// specified location or if an object member does exist, that member's value is replaced. /// /// The operation object MUST contain a "value" member whose content @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// For example: /// /// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" } - /// + /// /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-7 /// /// The copy operation. @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } /// /// A location cannot be moved into one of its children. - /// + /// /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-6 /// /// The move operation. @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// /// If removing an element from an array, any elements above the /// specified index are shifted one position to the left. - /// + /// /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-6 /// /// The remove operation. @@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters void Remove(Operation operation, object objectToApplyTo); /// - /// Using the "replace" operation he value at the target location is replaced + /// Using the "replace" operation the value at the target location is replaced /// with a new value. The operation object MUST contain a "value" member /// which specifies the replacement value. /// @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Adapters /// For example: /// /// { "op": "replace", "path": "/a/b/c", "value": 42 } - /// + /// /// See RFC 6902 https://tools.ietf.org/html/rfc6902#page-6 /// /// The replace operation. diff --git a/src/Features/JsonPatch/src/Helpers/GetValueResult.cs b/src/Features/JsonPatch/src/Helpers/GetValueResult.cs index e2e739a027..8e6cd3d60d 100644 --- a/src/Features/JsonPatch/src/Helpers/GetValueResult.cs +++ b/src/Features/JsonPatch/src/Helpers/GetValueResult.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.JsonPatch.Helpers public object PropertyValue { get; private set; } /// - /// HasError: true when an error occurred, the operation didn't complete succesfully + /// HasError: true when an error occurred, the operation didn't complete successfully /// public bool HasError { get; private set; } } diff --git a/src/Features/JsonPatch/src/Internal/JObjectAdapter.cs b/src/Features/JsonPatch/src/Internal/JObjectAdapter.cs new file mode 100644 index 0000000000..8354d2043b --- /dev/null +++ b/src/Features/JsonPatch/src/Internal/JObjectAdapter.cs @@ -0,0 +1,140 @@ +using Microsoft.AspNetCore.JsonPatch.Internal; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.AspNetCore.JsonPatch.Internal +{ + public class JObjectAdapter : IAdapter + { + public virtual bool TryAdd( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var obj = (JObject) target; + + obj[segment] = JToken.FromObject(value); + + errorMessage = null; + return true; + } + + public virtual bool TryGet( + object target, + string segment, + IContractResolver contractResolver, + out object value, + out string errorMessage) + { + var obj = (JObject) target; + + if (!obj.ContainsKey(segment)) + { + value = null; + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + value = obj[segment]; + errorMessage = null; + return true; + } + + public virtual bool TryRemove( + object target, + string segment, + IContractResolver contractResolver, + out string errorMessage) + { + var obj = (JObject) target; + + if (!obj.ContainsKey(segment)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + obj.Remove(segment); + errorMessage = null; + return true; + } + + public virtual bool TryReplace( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var obj = (JObject) target; + + if (!obj.ContainsKey(segment)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + obj[segment] = JToken.FromObject(value); + + errorMessage = null; + return true; + } + + public virtual bool TryTest( + object target, + string segment, + IContractResolver contractResolver, + object value, + out string errorMessage) + { + var obj = (JObject) target; + + if (!obj.ContainsKey(segment)) + { + errorMessage = Resources.FormatTargetLocationAtPathSegmentNotFound(segment); + return false; + } + + var currentValue = obj[segment]; + + if (currentValue == null || string.IsNullOrEmpty(currentValue.ToString())) + { + errorMessage = Resources.FormatValueForTargetSegmentCannotBeNullOrEmpty(segment); + return false; + } + + if (!JToken.DeepEquals(JsonConvert.SerializeObject(currentValue), JsonConvert.SerializeObject(value))) + { + errorMessage = Resources.FormatValueNotEqualToTestValue(currentValue, value, segment); + return false; + } + + errorMessage = null; + return true; + } + + public virtual bool TryTraverse( + object target, + string segment, + IContractResolver contractResolver, + out object nextTarget, + out string errorMessage) + { + var obj = (JObject) target; + + if (!obj.ContainsKey(segment)) + { + nextTarget = null; + errorMessage = null; + return false; + } + + nextTarget = obj[segment]; + errorMessage = null; + return true; + } + } +} \ No newline at end of file diff --git a/src/Features/JsonPatch/test/IntegrationTests/SimpleObjectIntegrationTest.cs b/src/Features/JsonPatch/test/IntegrationTests/SimpleObjectIntegrationTest.cs index 731e181697..d98e6ffdb6 100644 --- a/src/Features/JsonPatch/test/IntegrationTests/SimpleObjectIntegrationTest.cs +++ b/src/Features/JsonPatch/test/IntegrationTests/SimpleObjectIntegrationTest.cs @@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests Assert.Equal(newGuid, targetObject.GuidValue); } - // https://github.com/aspnet/AspNetCore/issues/3634 + // https://github.com/dotnet/aspnetcore/issues/3634 [Fact] public void Regression_AspNetCore3634() { @@ -160,7 +160,7 @@ namespace Microsoft.AspNetCore.JsonPatch.IntegrationTests var target = new Regression_AspNetCore3634_Object(); target.Object = @object; - // Act + // Act var ex = Assert.Throws(() => document.ApplyTo(target)); // Assert diff --git a/src/Features/JsonPatch/test/JsonPatchDocumentJObjectTest.cs b/src/Features/JsonPatch/test/JsonPatchDocumentJObjectTest.cs new file mode 100644 index 0000000000..271f100871 --- /dev/null +++ b/src/Features/JsonPatch/test/JsonPatchDocumentJObjectTest.cs @@ -0,0 +1,144 @@ +// 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.Collections.Generic; +using System.Dynamic; +using Microsoft.AspNetCore.JsonPatch.Exceptions; +using Microsoft.AspNetCore.JsonPatch.Operations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Xunit; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class JsonPatchDocumentJObjectTest + { + [Fact] + public void ApplyTo_Array_Add() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { Emails = new[] { "foo@bar.com" } })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("add", "/CustomData/Emails/-", null, "foo@baz.com")); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.Equal("foo@baz.com", model.CustomData["Emails"][1].Value()); + } + + [Fact] + public void ApplyTo_Model_Test1() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { Email = "foo@bar.com", Name = "Bar" })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("test", "/CustomData/Email", null, "foo@baz.com")); + patch.Operations.Add(new Operation("add", "/CustomData/Name", null, "Bar Baz")); + + // Act & Assert + Assert.Throws(() => patch.ApplyTo(model)); + } + + [Fact] + public void ApplyTo_Model_Test2() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { Email = "foo@bar.com", Name = "Bar" })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("test", "/CustomData/Email", null, "foo@bar.com")); + patch.Operations.Add(new Operation("add", "/CustomData/Name", null, "Bar Baz")); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.Equal("Bar Baz", model.CustomData["Name"].Value()); + } + + [Fact] + public void ApplyTo_Model_Copy() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { Email = "foo@bar.com" })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("copy", "/CustomData/UserName", "/CustomData/Email")); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.Equal("foo@bar.com", model.CustomData["UserName"].Value()); + } + + [Fact] + public void ApplyTo_Model_Remove() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { FirstName = "Foo", LastName = "Bar" })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("remove", "/CustomData/LastName", null)); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.False(model.CustomData.ContainsKey("LastName")); + } + + [Fact] + public void ApplyTo_Model_Move() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { FirstName = "Bar" })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("move", "/CustomData/LastName", "/CustomData/FirstName")); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.False(model.CustomData.ContainsKey("FirstName")); + Assert.Equal("Bar", model.CustomData["LastName"].Value()); + } + + [Fact] + public void ApplyTo_Model_Add() + { + // Arrange + var model = new ObjectWithJObject(); + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("add", "/CustomData/Name", null, "Foo")); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.Equal("Foo", model.CustomData["Name"].Value()); + } + + [Fact] + public void ApplyTo_Model_Replace() + { + // Arrange + var model = new ObjectWithJObject{ CustomData = JObject.FromObject(new { Email = "foo@bar.com", Name = "Bar" })}; + var patch = new JsonPatchDocument(); + + patch.Operations.Add(new Operation("replace", "/CustomData/Email", null, "foo@baz.com")); + + // Act + patch.ApplyTo(model); + + // Assert + Assert.Equal("foo@baz.com", model.CustomData["Email"].Value()); + } + } +} diff --git a/src/Features/JsonPatch/test/TestObjectModels/ObjectWithJObject.cs b/src/Features/JsonPatch/test/TestObjectModels/ObjectWithJObject.cs new file mode 100644 index 0000000000..188ca034d2 --- /dev/null +++ b/src/Features/JsonPatch/test/TestObjectModels/ObjectWithJObject.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json.Linq; + +namespace Microsoft.AspNetCore.JsonPatch +{ + public class ObjectWithJObject + { + public JObject CustomData { get; set; } = new JObject(); + } +} diff --git a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj index 66680a95a5..f843ded124 100644 --- a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj +++ b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj @@ -90,15 +90,17 @@ This package is an internal implementation of the .NET Core SDK and is not meant : %3B + x64_arm + x64_arm64 + x86_arm + crossgen $(CrossgenToolFileName).exe $(CrossgenToolFileName) - x64_arm\$(CrossgenToolPackagePath) - x64_arm64\$(CrossgenToolPackagePath) - x86_arm\$(CrossgenToolPackagePath) + $(CrossCompileDirectory)\$(CrossgenToolPackagePath) $([System.IO.Path]::Combine('$(NuGetPackageRoot)', 'microsoft.netcore.app.runtime.$(RuntimeIdentifier)', '$(MicrosoftNETCoreAppRuntimeVersion)')) $([MSBuild]::EnsureTrailingSlash('$(RuntimePackageRoot)')) @@ -167,6 +169,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant _BatchCopyToRedistLayout; _CreateInternalSharedFxArchive; _CreateRedistSharedFxArchive; + _InstallFrameworkIntoLocalDotNet; ResolveReferences; @@ -292,7 +295,9 @@ This package is an internal implementation of the .NET Core SDK and is not meant --> $(IntermediateOutputPath)crossgen\ - $(CrossgenToolDir)$(LibPrefix)clrjit$(LibExtension) + + $(RuntimePackageRoot)runtimes\$(RuntimeIdentifier)\native\$(LibPrefix)clrjit$(LibExtension) + $(RuntimepackageRoot)runtimes\$(CrossCompileDirectory)\native\$(LibPrefix)clrjit$(LibExtension) diff --git a/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj b/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj index e0719971e0..1a001aac14 100644 --- a/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj +++ b/src/Framework/test/Microsoft.AspNetCore.App.UnitTests.csproj @@ -3,7 +3,7 @@ $(DefaultNetCoreTargetFramework) Microsoft.AspNetCore - + false diff --git a/src/Framework/test/TargetingPackTests.cs b/src/Framework/test/TargetingPackTests.cs index ec8a646f48..8a2625b99d 100644 --- a/src/Framework/test/TargetingPackTests.cs +++ b/src/Framework/test/TargetingPackTests.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore _targetingPackRoot = Path.Combine(TestData.GetTestDataValue("TargetingPackLayoutRoot"), "packs", "Microsoft.AspNetCore.App.Ref", TestData.GetTestDataValue("TargetingPackVersion")); } - [Fact(Skip="https://github.com/aspnet/AspNetCore/issues/14832")] + [Fact] public void AssembliesAreReferenceAssemblies() { IEnumerable dlls = Directory.GetFiles(_targetingPackRoot, "*.dll", SearchOption.AllDirectories); @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore }); } - [Fact(Skip="https://github.com/aspnet/AspNetCore/issues/14832")] + [Fact] public void PlatformManifestListsAllFiles() { var platformManifestPath = Path.Combine(_targetingPackRoot, "data", "PlatformManifest.txt"); diff --git a/src/Hosting/Abstractions/ref/Microsoft.AspNetCore.Hosting.Abstractions.netcoreapp.cs b/src/Hosting/Abstractions/ref/Microsoft.AspNetCore.Hosting.Abstractions.netcoreapp.cs index 4a3b8668f1..6b12e045e8 100644 --- a/src/Hosting/Abstractions/ref/Microsoft.AspNetCore.Hosting.Abstractions.netcoreapp.cs +++ b/src/Hosting/Abstractions/ref/Microsoft.AspNetCore.Hosting.Abstractions.netcoreapp.cs @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Hosting public sealed partial class HostingStartupAttribute : System.Attribute { public HostingStartupAttribute(System.Type hostingStartupType) { } - public System.Type HostingStartupType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type HostingStartupType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.ObsoleteAttribute("This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.Extensions.Hosting.IHostApplicationLifetime.", false)] public partial interface IApplicationLifetime @@ -104,8 +104,8 @@ namespace Microsoft.AspNetCore.Hosting public partial class WebHostBuilderContext { public WebHostBuilderContext() { } - public Microsoft.Extensions.Configuration.IConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.Configuration.IConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class WebHostDefaults { diff --git a/src/Hosting/Hosting/ref/Microsoft.AspNetCore.Hosting.netcoreapp.cs b/src/Hosting/Hosting/ref/Microsoft.AspNetCore.Hosting.netcoreapp.cs index 5a17de6ee4..b87c115dea 100644 --- a/src/Hosting/Hosting/ref/Microsoft.AspNetCore.Hosting.netcoreapp.cs +++ b/src/Hosting/Hosting/ref/Microsoft.AspNetCore.Hosting.netcoreapp.cs @@ -73,8 +73,8 @@ namespace Microsoft.AspNetCore.Hosting.Server.Features public partial class ServerAddressesFeature : Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature { public ServerAddressesFeature() { } - public System.Collections.Generic.ICollection Addresses { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool PreferHostingUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.ICollection Addresses { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool PreferHostingUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Hosting.StaticWebAssets diff --git a/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs b/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs index 89c6b4e941..701855e913 100644 --- a/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs +++ b/src/Hosting/Hosting/src/GenericHost/GenericWebHostedService.cs @@ -173,6 +173,7 @@ namespace Microsoft.AspNetCore.Hosting { var exceptionDetailProvider = new ExceptionDetailsProvider( HostingEnvironment.ContentRootFileProvider, + Logger, sourceCodeLineCount: 6); model.ErrorDetails = exceptionDetailProvider.GetDetails(exception); diff --git a/src/Hosting/Hosting/src/Http/DefaultHttpContextFactory.cs b/src/Hosting/Hosting/src/Http/DefaultHttpContextFactory.cs index 08ecd9b057..2637a8b3a6 100644 --- a/src/Hosting/Hosting/src/Http/DefaultHttpContextFactory.cs +++ b/src/Hosting/Hosting/src/Http/DefaultHttpContextFactory.cs @@ -26,6 +26,8 @@ namespace Microsoft.AspNetCore.Http _serviceScopeFactory = serviceProvider.GetRequiredService(); } + internal IHttpContextAccessor HttpContextAccessor => _httpContextAccessor; + public HttpContext Create(IFeatureCollection featureCollection) { if (featureCollection is null) diff --git a/src/Hosting/Hosting/src/Internal/HostingApplication.cs b/src/Hosting/Hosting/src/Internal/HostingApplication.cs index c64426c0db..8432661215 100644 --- a/src/Hosting/Hosting/src/Internal/HostingApplication.cs +++ b/src/Hosting/Hosting/src/Internal/HostingApplication.cs @@ -96,6 +96,14 @@ namespace Microsoft.AspNetCore.Hosting if (_defaultHttpContextFactory != null) { _defaultHttpContextFactory.Dispose((DefaultHttpContext)httpContext); + + if (_defaultHttpContextFactory.HttpContextAccessor != null) + { + // Clear the HttpContext if the accessor was used. It's likely that the lifetime extends + // past the end of the http request and we want to avoid changing the reference from under + // consumers. + context.HttpContext = null; + } } else { @@ -114,6 +122,7 @@ namespace Microsoft.AspNetCore.Hosting public HttpContext HttpContext { get; set; } public IDisposable Scope { get; set; } public Activity Activity { get; set; } + internal HostingRequestStartingLog StartLog { get; set; } public long StartTimestamp { get; set; } internal bool HasDiagnosticListener { get; set; } @@ -125,6 +134,7 @@ namespace Microsoft.AspNetCore.Hosting Scope = null; Activity = null; + StartLog = null; StartTimestamp = 0; HasDiagnosticListener = false; diff --git a/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs b/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs index 65730d67ff..385bcbf46d 100644 --- a/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs +++ b/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs @@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Hosting } // Non-inline - LogRequestStarting(httpContext); + LogRequestStarting(context); } } context.StartTimestamp = startTimestamp; @@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Hosting { currentTimestamp = Stopwatch.GetTimestamp(); // Non-inline - LogRequestFinished(httpContext, startTimestamp, currentTimestamp); + LogRequestFinished(context, startTimestamp, currentTimestamp); } if (_diagnosticListener.IsEnabled()) @@ -167,30 +167,34 @@ namespace Microsoft.AspNetCore.Hosting } [MethodImpl(MethodImplOptions.NoInlining)] - private void LogRequestStarting(HttpContext httpContext) + private void LogRequestStarting(HostingApplication.Context context) { // IsEnabled is checked in the caller, so if we are here just log + var startLog = new HostingRequestStartingLog(context.HttpContext); + context.StartLog = startLog; + _logger.Log( logLevel: LogLevel.Information, eventId: LoggerEventIds.RequestStarting, - state: new HostingRequestStartingLog(httpContext), + state: startLog, exception: null, formatter: HostingRequestStartingLog.Callback); } [MethodImpl(MethodImplOptions.NoInlining)] - private void LogRequestFinished(HttpContext httpContext, long startTimestamp, long currentTimestamp) + private void LogRequestFinished(HostingApplication.Context context, long startTimestamp, long currentTimestamp) { // IsEnabled isn't checked in the caller, startTimestamp > 0 is used as a fast proxy check - // but that may be because diagnostics are enabled, which also uses startTimestamp, so check here - if (_logger.IsEnabled(LogLevel.Information)) + // but that may be because diagnostics are enabled, which also uses startTimestamp, + // so check if we logged the start event + if (context.StartLog != null) { var elapsed = new TimeSpan((long)(TimestampToTicks * (currentTimestamp - startTimestamp))); _logger.Log( logLevel: LogLevel.Information, eventId: LoggerEventIds.RequestFinished, - state: new HostingRequestFinishedLog(httpContext, elapsed), + state: new HostingRequestFinishedLog(context, elapsed), exception: null, formatter: HostingRequestFinishedLog.Callback); } diff --git a/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs b/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs index 63fd5f0921..09a132851d 100644 --- a/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs +++ b/src/Hosting/Hosting/src/Internal/HostingRequestFinishedLog.cs @@ -9,51 +9,56 @@ using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Hosting { + using static HostingRequestStartingLog; + internal class HostingRequestFinishedLog : IReadOnlyList> { internal static readonly Func Callback = (state, exception) => ((HostingRequestFinishedLog)state).ToString(); - private readonly HttpContext _httpContext; - private readonly TimeSpan _elapsed; + private readonly HostingApplication.Context _context; private string _cachedToString; + public TimeSpan Elapsed { get; } - public int Count => 3; + public int Count => 11; public KeyValuePair this[int index] { get { - switch (index) + var request = _context.HttpContext.Request; + var response = _context.HttpContext.Response; + + return index switch { - case 0: - return new KeyValuePair("ElapsedMilliseconds", _elapsed.TotalMilliseconds); - case 1: - return new KeyValuePair("StatusCode", _httpContext.Response.StatusCode); - case 2: - return new KeyValuePair("ContentType", _httpContext.Response.ContentType); - default: - throw new IndexOutOfRangeException(nameof(index)); - } + 0 => new KeyValuePair("ElapsedMilliseconds", Elapsed.TotalMilliseconds), + 1 => new KeyValuePair(nameof(response.StatusCode), response.StatusCode), + 2 => new KeyValuePair(nameof(response.ContentType), response.ContentType), + 3 => new KeyValuePair(nameof(response.ContentLength), response.ContentLength), + 4 => new KeyValuePair(nameof(request.Protocol), request.Protocol), + 5 => new KeyValuePair(nameof(request.Method), request.Method), + 6 => new KeyValuePair(nameof(request.Scheme), request.Scheme), + 7 => new KeyValuePair(nameof(request.Host), request.Host.Value), + 8 => new KeyValuePair(nameof(request.PathBase), request.PathBase.Value), + 9 => new KeyValuePair(nameof(request.Path), request.Path.Value), + 10 => new KeyValuePair(nameof(request.QueryString), request.QueryString.Value), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; } } - public HostingRequestFinishedLog(HttpContext httpContext, TimeSpan elapsed) + public HostingRequestFinishedLog(HostingApplication.Context context, TimeSpan elapsed) { - _httpContext = httpContext; - _elapsed = elapsed; + _context = context; + Elapsed = elapsed; } public override string ToString() { if (_cachedToString == null) { - _cachedToString = string.Format( - CultureInfo.InvariantCulture, - "Request finished in {0}ms {1} {2}", - _elapsed.TotalMilliseconds, - _httpContext.Response.StatusCode, - _httpContext.Response.ContentType); + var response = _context.HttpContext.Response; + _cachedToString = $"Request finished {_context.StartLog.ToStringWithoutPreamble()} - {response.StatusCode.ToString(CultureInfo.InvariantCulture)} {ValueOrEmptyMarker(response.ContentLength)} {EscapedValueOrEmptyMarker(response.ContentType)} {Elapsed.TotalMilliseconds.ToString("0.0000", CultureInfo.InvariantCulture)}ms"; } return _cachedToString; diff --git a/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs b/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs index 279fa06aed..3a7586b1c9 100644 --- a/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs +++ b/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs @@ -5,12 +5,16 @@ using System; using System.Collections; using System.Collections.Generic; using System.Globalization; +using System.Net; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Hosting { internal class HostingRequestStartingLog : IReadOnlyList> { + private const string LogPreamble = "Request starting "; + private const string EmptyEntry = "-"; + internal static readonly Func Callback = (state, exception) => ((HostingRequestStartingLog)state).ToString(); private readonly HttpRequest _request; @@ -19,35 +23,19 @@ namespace Microsoft.AspNetCore.Hosting public int Count => 9; - public KeyValuePair this[int index] + public KeyValuePair this[int index] => index switch { - get - { - switch (index) - { - case 0: - return new KeyValuePair("Protocol", _request.Protocol); - case 1: - return new KeyValuePair("Method", _request.Method); - case 2: - return new KeyValuePair("ContentType", _request.ContentType); - case 3: - return new KeyValuePair("ContentLength", _request.ContentLength); - case 4: - return new KeyValuePair("Scheme", _request.Scheme); - case 5: - return new KeyValuePair("Host", _request.Host.ToString()); - case 6: - return new KeyValuePair("PathBase", _request.PathBase.ToString()); - case 7: - return new KeyValuePair("Path", _request.Path.ToString()); - case 8: - return new KeyValuePair("QueryString", _request.QueryString.ToString()); - default: - throw new IndexOutOfRangeException(nameof(index)); - } - } - } + 0 => new KeyValuePair(nameof(_request.Protocol), _request.Protocol), + 1 => new KeyValuePair(nameof(_request.Method), _request.Method), + 2 => new KeyValuePair(nameof(_request.ContentType), _request.ContentType), + 3 => new KeyValuePair(nameof(_request.ContentLength), _request.ContentLength), + 4 => new KeyValuePair(nameof(_request.Scheme), _request.Scheme), + 5 => new KeyValuePair(nameof(_request.Host), _request.Host.Value), + 6 => new KeyValuePair(nameof(_request.PathBase), _request.PathBase.Value), + 7 => new KeyValuePair(nameof(_request.Path), _request.Path.Value), + 8 => new KeyValuePair(nameof(_request.QueryString), _request.QueryString.Value), + _ => throw new IndexOutOfRangeException(nameof(index)), + }; public HostingRequestStartingLog(HttpContext httpContext) { @@ -58,18 +46,8 @@ namespace Microsoft.AspNetCore.Hosting { if (_cachedToString == null) { - _cachedToString = string.Format( - CultureInfo.InvariantCulture, - "Request starting {0} {1} {2}://{3}{4}{5}{6} {7} {8}", - _request.Protocol, - _request.Method, - _request.Scheme, - _request.Host.Value, - _request.PathBase.Value, - _request.Path.Value, - _request.QueryString.Value, - _request.ContentType, - _request.ContentLength); + var request = _request; + _cachedToString = $"{LogPreamble}{request.Protocol} {request.Method} {request.Scheme}://{request.Host.Value}{request.PathBase.Value}{request.Path.Value}{request.QueryString.Value} {EscapedValueOrEmptyMarker(request.ContentType)} {ValueOrEmptyMarker(request.ContentLength)}"; ; } return _cachedToString; @@ -87,5 +65,15 @@ namespace Microsoft.AspNetCore.Hosting { return GetEnumerator(); } + + internal string ToStringWithoutPreamble() + => ToString().Substring(LogPreamble.Length); + + internal static string EscapedValueOrEmptyMarker(string potentialValue) + // Encode space as + + => potentialValue?.Length > 0 ? potentialValue.Replace(' ', '+') : EmptyEntry; + + internal static string ValueOrEmptyMarker(T? potentialValue) where T : struct, IFormattable + => potentialValue?.ToString(null, CultureInfo.InvariantCulture) ?? EmptyEntry; } } diff --git a/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs b/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs index a7c75fafdc..8c391bfa2d 100644 --- a/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs +++ b/src/Hosting/Hosting/src/Internal/LoggerEventIds.cs @@ -1,21 +1,22 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Hosting { internal static class LoggerEventIds { - public const int RequestStarting = 1; - public const int RequestFinished = 2; - public const int Starting = 3; - public const int Started = 4; - public const int Shutdown = 5; - public const int ApplicationStartupException = 6; - public const int ApplicationStoppingException = 7; - public const int ApplicationStoppedException = 8; - public const int HostedServiceStartException = 9; - public const int HostedServiceStopException = 10; - public const int HostingStartupAssemblyException = 11; - public const int ServerShutdownException = 12; + public static readonly EventId RequestStarting = new EventId(1, "RequestStarting"); + public static readonly EventId RequestFinished = new EventId(2, "RequestFinished"); + public static readonly EventId Starting = new EventId(3, "Starting"); + public static readonly EventId Started = new EventId(4, "Started"); + public static readonly EventId Shutdown = new EventId(5, "Shutdown"); + public static readonly EventId ApplicationStartupException = new EventId(6, "ApplicationStartupException"); + public static readonly EventId ApplicationStoppingException = new EventId(7, "ApplicationStoppingException"); + public static readonly EventId ApplicationStoppedException = new EventId(8, "ApplicationStoppedException"); + public static readonly EventId HostedServiceStartException = new EventId(9, "HostedServiceStartException"); + public static readonly EventId HostedServiceStopException = new EventId(10, "HostedServiceStopException"); + public static readonly EventId HostingStartupAssemblyException = new EventId(11, "HostingStartupAssemblyException"); + public static readonly EventId ServerShutdownException = new EventId(12, "ServerShutdownException"); } } diff --git a/src/Hosting/Hosting/src/Internal/WebHost.cs b/src/Hosting/Hosting/src/Internal/WebHost.cs index 6e976959e7..b016f751a8 100644 --- a/src/Hosting/Hosting/src/Internal/WebHost.cs +++ b/src/Hosting/Hosting/src/Internal/WebHost.cs @@ -270,6 +270,7 @@ namespace Microsoft.AspNetCore.Hosting { var exceptionDetailProvider = new ExceptionDetailsProvider( hostingEnv.ContentRootFileProvider, + logger, sourceCodeLineCount: 6); model.ErrorDetails = exceptionDetailProvider.GetDetails(ex); @@ -355,7 +356,7 @@ namespace Microsoft.AspNetCore.Hosting public void Dispose() { - DisposeAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + DisposeAsync().GetAwaiter().GetResult(); } public async ValueTask DisposeAsync() diff --git a/src/Hosting/Hosting/src/Internal/WebHostLifetime.cs b/src/Hosting/Hosting/src/Internal/WebHostLifetime.cs index 19d9006647..12c9ab3843 100644 --- a/src/Hosting/Hosting/src/Internal/WebHostLifetime.cs +++ b/src/Hosting/Hosting/src/Internal/WebHostLifetime.cs @@ -55,14 +55,14 @@ namespace Microsoft.AspNetCore.Hosting if (_exitedGracefully) { // On Linux if the shutdown is triggered by SIGTERM then that's signaled with the 143 exit code. - // Suppress that since we shut down gracefully. https://github.com/aspnet/AspNetCore/issues/6526 + // Suppress that since we shut down gracefully. https://github.com/dotnet/aspnetcore/issues/6526 Environment.ExitCode = 0; } } private void Shutdown() { - try + try { if (!_cts.IsCancellationRequested) { diff --git a/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs b/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs new file mode 100644 index 0000000000..385424fa67 --- /dev/null +++ b/src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs @@ -0,0 +1,532 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.Logging; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Hosting.Tests +{ + public class HostingApplicationDiagnosticsTests + { + [Fact] + public void DisposeContextDoesNotThrowWhenContextScopeIsNull() + { + // Arrange + var hostingApplication = CreateApplication(out var features); + var context = hostingApplication.CreateContext(features); + + // Act/Assert + hostingApplication.DisposeContext(context, null); + } + + [Fact] + public void CreateContextWithDisabledLoggerDoesNotCreateActivity() + { + // Arrange + var hostingApplication = CreateApplication(out var features); + + // Act + hostingApplication.CreateContext(features); + + Assert.Null(Activity.Current); + } + + [Fact] + public void CreateContextWithEnabledLoggerCreatesActivityAndSetsActivityInScope() + { + // Arrange + var logger = new LoggerWithScopes(isEnabled: true); + var hostingApplication = CreateApplication(out var features, logger: logger); + + // Act + var context = hostingApplication.CreateContext(features); + + Assert.Single(logger.Scopes); + var pairs = ((IReadOnlyList>)logger.Scopes[0]).ToDictionary(p => p.Key, p => p.Value); + Assert.Equal(Activity.Current.Id, pairs["SpanId"].ToString()); + Assert.Equal(Activity.Current.RootId, pairs["TraceId"].ToString()); + Assert.Equal(string.Empty, pairs["ParentId"]?.ToString()); + } + + [Fact] + public void CreateContextWithEnabledLoggerAndRequestIdCreatesActivityAndSetsActivityInScope() + { + // Arrange + + // Generate an id we can use for the request id header (in the correct format) + var activity = new Activity("IncomingRequest"); + activity.Start(); + var id = activity.Id; + activity.Stop(); + + var logger = new LoggerWithScopes(isEnabled: true); + var hostingApplication = CreateApplication(out var features, logger: logger, configure: context => + { + context.Request.Headers["Request-Id"] = id; + }); + + // Act + var context = hostingApplication.CreateContext(features); + + Assert.Single(logger.Scopes); + var pairs = ((IReadOnlyList>)logger.Scopes[0]).ToDictionary(p => p.Key, p => p.Value); + Assert.Equal(Activity.Current.Id, pairs["SpanId"].ToString()); + Assert.Equal(Activity.Current.RootId, pairs["TraceId"].ToString()); + Assert.Equal(id, pairs["ParentId"].ToString()); + } + + [Fact] + public void ActivityStopDoesNotFireIfNoListenerAttachedForStart() + { + // Arrange + var diagnosticListener = new DiagnosticListener("DummySource"); + var logger = new LoggerWithScopes(isEnabled: true); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener, logger: logger); + var startFired = false; + var stopFired = false; + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + // This should not fire + if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") + { + startFired = true; + } + + // This should not fire + if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop") + { + stopFired = true; + } + }), + (s, o, arg3) => + { + // The events are off + return false; + }); + + + // Act + var context = hostingApplication.CreateContext(features); + + hostingApplication.DisposeContext(context, exception: null); + + Assert.False(startFired); + Assert.False(stopFired); + Assert.Null(Activity.Current); + } + + [Fact] + public void ActivityIsNotCreatedWhenIsEnabledForActivityIsFalse() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool eventsFired = false; + bool isEnabledActivityFired = false; + bool isEnabledStartFired = false; + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"); + }), (s, o, arg3) => + { + if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn") + { + Assert.IsAssignableFrom(o); + isEnabledActivityFired = true; + } + if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") + { + isEnabledStartFired = true; + } + return false; + }); + + hostingApplication.CreateContext(features); + Assert.Null(Activity.Current); + Assert.True(isEnabledActivityFired); + Assert.False(isEnabledStartFired); + Assert.False(eventsFired); + } + + [Fact] + public void ActivityIsCreatedButNotLoggedWhenIsEnabledForActivityStartIsFalse() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool eventsFired = false; + bool isEnabledStartFired = false; + bool isEnabledActivityFired = false; + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"); + }), (s, o, arg3) => + { + if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn") + { + Assert.IsAssignableFrom(o); + isEnabledActivityFired = true; + return true; + } + + if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") + { + isEnabledStartFired = true; + return false; + } + return true; + }); + + hostingApplication.CreateContext(features); + Assert.NotNull(Activity.Current); + Assert.True(isEnabledActivityFired); + Assert.True(isEnabledStartFired); + Assert.False(eventsFired); + } + + [Fact] + public void ActivityIsCreatedAndLogged() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool startCalled = false; + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") + { + startCalled = true; + Assert.NotNull(pair.Value); + Assert.NotNull(Activity.Current); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + AssertProperty(pair.Value, "HttpContext"); + } + })); + + hostingApplication.CreateContext(features); + Assert.NotNull(Activity.Current); + Assert.True(startCalled); + } + + [Fact] + public void ActivityIsStoppedDuringStopCall() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool endCalled = false; + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop") + { + endCalled = true; + + Assert.NotNull(Activity.Current); + Assert.True(Activity.Current.Duration > TimeSpan.Zero); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + AssertProperty(pair.Value, "HttpContext"); + } + })); + + var context = hostingApplication.CreateContext(features); + hostingApplication.DisposeContext(context, null); + Assert.True(endCalled); + } + + [Fact] + public void ActivityIsStoppedDuringUnhandledExceptionCall() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool endCalled = false; + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop") + { + endCalled = true; + Assert.NotNull(Activity.Current); + Assert.True(Activity.Current.Duration > TimeSpan.Zero); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + AssertProperty(pair.Value, "HttpContext"); + } + })); + + var context = hostingApplication.CreateContext(features); + hostingApplication.DisposeContext(context, new Exception()); + Assert.True(endCalled); + } + + [Fact] + public void ActivityIsAvailableDuringUnhandledExceptionCall() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool endCalled = false; + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => + { + if (pair.Key == "Microsoft.AspNetCore.Hosting.UnhandledException") + { + endCalled = true; + Assert.NotNull(Activity.Current); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + } + })); + + var context = hostingApplication.CreateContext(features); + hostingApplication.DisposeContext(context, new Exception()); + Assert.True(endCalled); + } + + [Fact] + public void ActivityIsAvailibleDuringRequest() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }), + s => + { + if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn")) + { + return true; + } + return false; + }); + + hostingApplication.CreateContext(features); + + Assert.NotNull(Activity.Current); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + } + + [Fact] + public void ActivityParentIdAndBaggeReadFromHeaders() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }), + s => + { + if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn")) + { + return true; + } + return false; + }); + + features.Set(new HttpRequestFeature() + { + Headers = new HeaderDictionary() + { + {"Request-Id", "ParentId1"}, + {"Correlation-Context", "Key1=value1, Key2=value2"} + } + }); + hostingApplication.CreateContext(features); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + Assert.Equal("ParentId1", Activity.Current.ParentId); + Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key1" && pair.Value == "value1"); + Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key2" && pair.Value == "value2"); + } + + + [Fact] + public void ActivityTraceParentAndTraceStateFromHeaders() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }), + s => + { + if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn")) + { + return true; + } + return false; + }); + + features.Set(new HttpRequestFeature() + { + Headers = new HeaderDictionary() + { + {"traceparent", "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"}, + {"tracestate", "TraceState1"}, + {"Correlation-Context", "Key1=value1, Key2=value2"} + } + }); + hostingApplication.CreateContext(features); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); + Assert.Equal(ActivityIdFormat.W3C, Activity.Current.IdFormat); + Assert.Equal("0123456789abcdef0123456789abcdef", Activity.Current.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", Activity.Current.ParentSpanId.ToHexString()); + Assert.Equal("TraceState1", Activity.Current.TraceStateString); + + Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key1" && pair.Value == "value1"); + Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key2" && pair.Value == "value2"); + } + + [Fact] + public void ActivityOnExportHookIsCalled() + { + var diagnosticListener = new DiagnosticListener("DummySource"); + var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); + + bool onActivityImportCalled = false; + diagnosticListener.Subscribe( + observer: new CallbackDiagnosticListener(pair => { }), + isEnabled: (s, o, _) => true, + onActivityImport: (activity, context) => + { + onActivityImportCalled = true; + Assert.Null(Activity.Current); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", activity.OperationName); + Assert.NotNull(context); + Assert.IsAssignableFrom(context); + + activity.ActivityTraceFlags = ActivityTraceFlags.Recorded; + }); + + hostingApplication.CreateContext(features); + + Assert.True(onActivityImportCalled); + Assert.NotNull(Activity.Current); + Assert.True(Activity.Current.Recorded); + } + + + private static void AssertProperty(object o, string name) + { + Assert.NotNull(o); + var property = o.GetType().GetTypeInfo().GetProperty(name, BindingFlags.Instance | BindingFlags.Public); + Assert.NotNull(property); + var value = property.GetValue(o); + Assert.NotNull(value); + Assert.IsAssignableFrom(value); + } + + private static HostingApplication CreateApplication(out FeatureCollection features, + DiagnosticListener diagnosticListener = null, ILogger logger = null, Action configure = null) + { + var httpContextFactory = new Mock(); + + features = new FeatureCollection(); + features.Set(new HttpRequestFeature()); + var context = new DefaultHttpContext(features); + configure?.Invoke(context); + httpContextFactory.Setup(s => s.Create(It.IsAny())).Returns(context); + httpContextFactory.Setup(s => s.Dispose(It.IsAny())); + + var hostingApplication = new HostingApplication( + ctx => Task.CompletedTask, + logger ?? new NullScopeLogger(), + diagnosticListener ?? new NoopDiagnosticListener(), + httpContextFactory.Object); + + return hostingApplication; + } + + private class NullScopeLogger : ILogger + { + private readonly bool _isEnabled; + public NullScopeLogger(bool isEnabled = false) + { + _isEnabled = isEnabled; + } + + public IDisposable BeginScope(TState state) => null; + + public bool IsEnabled(LogLevel logLevel) => _isEnabled; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + } + } + + private class LoggerWithScopes : ILogger + { + private readonly bool _isEnabled; + public LoggerWithScopes(bool isEnabled = false) + { + _isEnabled = isEnabled; + } + + public IDisposable BeginScope(TState state) + { + Scopes.Add(state); + return new Scope(); + } + + public List Scopes { get; set; } = new List(); + + public bool IsEnabled(LogLevel logLevel) => _isEnabled; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + + } + + private class Scope : IDisposable + { + public void Dispose() + { + } + } + } + + private class NoopDiagnosticListener : DiagnosticListener + { + private readonly bool _isEnabled; + + public NoopDiagnosticListener(bool isEnabled = false) : base("DummyListener") + { + _isEnabled = isEnabled; + } + + public override bool IsEnabled(string name) => _isEnabled; + + public override void Write(string name, object value) + { + } + } + + private class CallbackDiagnosticListener : IObserver> + { + private readonly Action> _callback; + + public CallbackDiagnosticListener(Action> callback) + { + _callback = callback; + } + + public void OnNext(KeyValuePair value) + { + _callback(value); + } + + public void OnError(Exception error) + { + } + + public void OnCompleted() + { + } + } + } +} diff --git a/src/Hosting/Hosting/test/HostingApplicationTests.cs b/src/Hosting/Hosting/test/HostingApplicationTests.cs index 64d832eb0c..4dd9863718 100644 --- a/src/Hosting/Hosting/test/HostingApplicationTests.cs +++ b/src/Hosting/Hosting/test/HostingApplicationTests.cs @@ -1,532 +1,136 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Reflection; using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting.Server.Abstractions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; using Moq; using Xunit; +using static Microsoft.AspNetCore.Hosting.HostingApplication; namespace Microsoft.AspNetCore.Hosting.Tests { public class HostingApplicationTests { [Fact] - public void DisposeContextDoesNotThrowWhenContextScopeIsNull() + public void DisposeContextDoesNotClearHttpContextIfDefaultHttpContextFactoryUsed() { // Arrange - var hostingApplication = CreateApplication(out var features); + var hostingApplication = CreateApplication(); + var httpContext = new DefaultHttpContext(); + + var context = hostingApplication.CreateContext(httpContext.Features); + Assert.NotNull(context.HttpContext); + + // Act/Assert + hostingApplication.DisposeContext(context, null); + Assert.NotNull(context.HttpContext); + } + + [Fact] + public void DisposeContextClearsHttpContextIfIHttpContextAccessorIsActive() + { + // Arrange + var hostingApplication = CreateApplication(useHttpContextAccessor: true); + var httpContext = new DefaultHttpContext(); + + var context = hostingApplication.CreateContext(httpContext.Features); + Assert.NotNull(context.HttpContext); + + // Act/Assert + hostingApplication.DisposeContext(context, null); + Assert.Null(context.HttpContext); + } + + [Fact] + public void CreateContextReinitializesPreviouslyStoredDefaultHttpContext() + { + // Arrange + var hostingApplication = CreateApplication(); + var features = new FeaturesWithContext(new DefaultHttpContext().Features); + var previousContext = new DefaultHttpContext(); + // Pretend like we had previous HttpContext + features.HostContext = new Context(); + features.HostContext.HttpContext = previousContext; + var context = hostingApplication.CreateContext(features); + Assert.Same(previousContext, context.HttpContext); + + // Act/Assert + hostingApplication.DisposeContext(context, null); + Assert.Same(previousContext, context.HttpContext); + } + + [Fact] + public void CreateContextCreatesNewContextIfNotUsingDefaultHttpContextFactory() + { + // Arrange + var factory = new Mock(); + factory.Setup(m => m.Create(It.IsAny())).Returns(f => new DefaultHttpContext(f)); + factory.Setup(m => m.Dispose(It.IsAny())).Callback(() => { }); + + var hostingApplication = CreateApplication(factory.Object); + var features = new FeaturesWithContext(new DefaultHttpContext().Features); + var previousContext = new DefaultHttpContext(); + // Pretend like we had previous HttpContext + features.HostContext = new Context(); + features.HostContext.HttpContext = previousContext; + + var context = hostingApplication.CreateContext(features); + Assert.NotSame(previousContext, context.HttpContext); // Act/Assert hostingApplication.DisposeContext(context, null); } - [Fact] - public void CreateContextWithDisabledLoggerDoesNotCreateActivity() + private static HostingApplication CreateApplication(IHttpContextFactory httpContextFactory = null, bool useHttpContextAccessor = false) { - // Arrange - var hostingApplication = CreateApplication(out var features); - - // Act - hostingApplication.CreateContext(features); - - Assert.Null(Activity.Current); - } - - [Fact] - public void CreateContextWithEnabledLoggerCreatesActivityAndSetsActivityInScope() - { - // Arrange - var logger = new LoggerWithScopes(isEnabled: true); - var hostingApplication = CreateApplication(out var features, logger: logger); - - // Act - var context = hostingApplication.CreateContext(features); - - Assert.Single(logger.Scopes); - var pairs = ((IReadOnlyList>)logger.Scopes[0]).ToDictionary(p => p.Key, p => p.Value); - Assert.Equal(Activity.Current.Id, pairs["SpanId"].ToString()); - Assert.Equal(Activity.Current.RootId, pairs["TraceId"].ToString()); - Assert.Equal(string.Empty, pairs["ParentId"]?.ToString()); - } - - [Fact] - public void CreateContextWithEnabledLoggerAndRequestIdCreatesActivityAndSetsActivityInScope() - { - // Arrange - - // Generate an id we can use for the request id header (in the correct format) - var activity = new Activity("IncomingRequest"); - activity.Start(); - var id = activity.Id; - activity.Stop(); - - var logger = new LoggerWithScopes(isEnabled: true); - var hostingApplication = CreateApplication(out var features, logger: logger, configure: context => + var services = new ServiceCollection(); + services.AddOptions(); + if (useHttpContextAccessor) { - context.Request.Headers["Request-Id"] = id; - }); + services.AddHttpContextAccessor(); + } - // Act - var context = hostingApplication.CreateContext(features); - - Assert.Single(logger.Scopes); - var pairs = ((IReadOnlyList>)logger.Scopes[0]).ToDictionary(p => p.Key, p => p.Value); - Assert.Equal(Activity.Current.Id, pairs["SpanId"].ToString()); - Assert.Equal(Activity.Current.RootId, pairs["TraceId"].ToString()); - Assert.Equal(id, pairs["ParentId"].ToString()); - } - - [Fact] - public void ActivityStopDoesNotFireIfNoListenerAttachedForStart() - { - // Arrange - var diagnosticListener = new DiagnosticListener("DummySource"); - var logger = new LoggerWithScopes(isEnabled: true); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener, logger: logger); - var startFired = false; - var stopFired = false; - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - // This should not fire - if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") - { - startFired = true; - } - - // This should not fire - if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop") - { - stopFired = true; - } - }), - (s, o, arg3) => - { - // The events are off - return false; - }); - - - // Act - var context = hostingApplication.CreateContext(features); - - hostingApplication.DisposeContext(context, exception: null); - - Assert.False(startFired); - Assert.False(stopFired); - Assert.Null(Activity.Current); - } - - [Fact] - public void ActivityIsNotCreatedWhenIsEnabledForActivityIsFalse() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool eventsFired = false; - bool isEnabledActivityFired = false; - bool isEnabledStartFired = false; - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"); - }), (s, o, arg3) => - { - if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn") - { - Assert.IsAssignableFrom(o); - isEnabledActivityFired = true; - } - if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") - { - isEnabledStartFired = true; - } - return false; - }); - - hostingApplication.CreateContext(features); - Assert.Null(Activity.Current); - Assert.True(isEnabledActivityFired); - Assert.False(isEnabledStartFired); - Assert.False(eventsFired); - } - - [Fact] - public void ActivityIsCreatedButNotLoggedWhenIsEnabledForActivityStartIsFalse() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool eventsFired = false; - bool isEnabledStartFired = false; - bool isEnabledActivityFired = false; - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - eventsFired |= pair.Key.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn"); - }), (s, o, arg3) => - { - if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn") - { - Assert.IsAssignableFrom(o); - isEnabledActivityFired = true; - return true; - } - - if (s == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") - { - isEnabledStartFired = true; - return false; - } - return true; - }); - - hostingApplication.CreateContext(features); - Assert.NotNull(Activity.Current); - Assert.True(isEnabledActivityFired); - Assert.True(isEnabledStartFired); - Assert.False(eventsFired); - } - - [Fact] - public void ActivityIsCreatedAndLogged() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool startCalled = false; - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start") - { - startCalled = true; - Assert.NotNull(pair.Value); - Assert.NotNull(Activity.Current); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - AssertProperty(pair.Value, "HttpContext"); - } - })); - - hostingApplication.CreateContext(features); - Assert.NotNull(Activity.Current); - Assert.True(startCalled); - } - - [Fact] - public void ActivityIsStoppedDuringStopCall() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool endCalled = false; - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop") - { - endCalled = true; - - Assert.NotNull(Activity.Current); - Assert.True(Activity.Current.Duration > TimeSpan.Zero); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - AssertProperty(pair.Value, "HttpContext"); - } - })); - - var context = hostingApplication.CreateContext(features); - hostingApplication.DisposeContext(context, null); - Assert.True(endCalled); - } - - [Fact] - public void ActivityIsStoppedDuringUnhandledExceptionCall() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool endCalled = false; - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - if (pair.Key == "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop") - { - endCalled = true; - Assert.NotNull(Activity.Current); - Assert.True(Activity.Current.Duration > TimeSpan.Zero); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - AssertProperty(pair.Value, "HttpContext"); - } - })); - - var context = hostingApplication.CreateContext(features); - hostingApplication.DisposeContext(context, new Exception()); - Assert.True(endCalled); - } - - [Fact] - public void ActivityIsAvailableDuringUnhandledExceptionCall() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool endCalled = false; - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => - { - if (pair.Key == "Microsoft.AspNetCore.Hosting.UnhandledException") - { - endCalled = true; - Assert.NotNull(Activity.Current); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - } - })); - - var context = hostingApplication.CreateContext(features); - hostingApplication.DisposeContext(context, new Exception()); - Assert.True(endCalled); - } - - [Fact] - public void ActivityIsAvailibleDuringRequest() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }), - s => - { - if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn")) - { - return true; - } - return false; - }); - - hostingApplication.CreateContext(features); - - Assert.NotNull(Activity.Current); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - } - - [Fact] - public void ActivityParentIdAndBaggeReadFromHeaders() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }), - s => - { - if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn")) - { - return true; - } - return false; - }); - - features.Set(new HttpRequestFeature() - { - Headers = new HeaderDictionary() - { - {"Request-Id", "ParentId1"}, - {"Correlation-Context", "Key1=value1, Key2=value2"} - } - }); - hostingApplication.CreateContext(features); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - Assert.Equal("ParentId1", Activity.Current.ParentId); - Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key1" && pair.Value == "value1"); - Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key2" && pair.Value == "value2"); - } - - - [Fact] - public void ActivityTraceParentAndTraceStateFromHeaders() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - diagnosticListener.Subscribe(new CallbackDiagnosticListener(pair => { }), - s => - { - if (s.StartsWith("Microsoft.AspNetCore.Hosting.HttpRequestIn")) - { - return true; - } - return false; - }); - - features.Set(new HttpRequestFeature() - { - Headers = new HeaderDictionary() - { - {"traceparent", "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"}, - {"tracestate", "TraceState1"}, - {"Correlation-Context", "Key1=value1, Key2=value2"} - } - }); - hostingApplication.CreateContext(features); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", Activity.Current.OperationName); - Assert.Equal(ActivityIdFormat.W3C, Activity.Current.IdFormat); - Assert.Equal("0123456789abcdef0123456789abcdef", Activity.Current.TraceId.ToHexString()); - Assert.Equal("0123456789abcdef", Activity.Current.ParentSpanId.ToHexString()); - Assert.Equal("TraceState1", Activity.Current.TraceStateString); - - Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key1" && pair.Value == "value1"); - Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key2" && pair.Value == "value2"); - } - - [Fact] - public void ActivityOnExportHookIsCalled() - { - var diagnosticListener = new DiagnosticListener("DummySource"); - var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener); - - bool onActivityImportCalled = false; - diagnosticListener.Subscribe( - observer: new CallbackDiagnosticListener(pair => { }), - isEnabled: (s, o, _) => true, - onActivityImport: (activity, context) => - { - onActivityImportCalled = true; - Assert.Null(Activity.Current); - Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", activity.OperationName); - Assert.NotNull(context); - Assert.IsAssignableFrom(context); - - activity.ActivityTraceFlags = ActivityTraceFlags.Recorded; - }); - - hostingApplication.CreateContext(features); - - Assert.True(onActivityImportCalled); - Assert.NotNull(Activity.Current); - Assert.True(Activity.Current.Recorded); - } - - - private static void AssertProperty(object o, string name) - { - Assert.NotNull(o); - var property = o.GetType().GetTypeInfo().GetProperty(name, BindingFlags.Instance | BindingFlags.Public); - Assert.NotNull(property); - var value = property.GetValue(o); - Assert.NotNull(value); - Assert.IsAssignableFrom(value); - } - - private static HostingApplication CreateApplication(out FeatureCollection features, - DiagnosticListener diagnosticListener = null, ILogger logger = null, Action configure = null) - { - var httpContextFactory = new Mock(); - - features = new FeatureCollection(); - features.Set(new HttpRequestFeature()); - var context = new DefaultHttpContext(features); - configure?.Invoke(context); - httpContextFactory.Setup(s => s.Create(It.IsAny())).Returns(context); - httpContextFactory.Setup(s => s.Dispose(It.IsAny())); + httpContextFactory ??= new DefaultHttpContextFactory(services.BuildServiceProvider()); var hostingApplication = new HostingApplication( ctx => Task.CompletedTask, - logger ?? new NullScopeLogger(), - diagnosticListener ?? new NoopDiagnosticListener(), - httpContextFactory.Object); + NullLogger.Instance, + new DiagnosticListener("Microsoft.AspNetCore"), + httpContextFactory); return hostingApplication; } - private class NullScopeLogger : ILogger + private class FeaturesWithContext : IHostContextContainer, IFeatureCollection { - private readonly bool _isEnabled; - public NullScopeLogger(bool isEnabled = false) + public FeaturesWithContext(IFeatureCollection features) { - _isEnabled = isEnabled; + Features = features; } - public IDisposable BeginScope(TState state) => null; + public IFeatureCollection Features { get; } - public bool IsEnabled(LogLevel logLevel) => _isEnabled; + public object this[Type key] { get => Features[key]; set => Features[key] = value; } - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - } - } + public T HostContext { get; set; } - private class LoggerWithScopes : ILogger - { - private readonly bool _isEnabled; - public LoggerWithScopes(bool isEnabled = false) - { - _isEnabled = isEnabled; - } + public bool IsReadOnly => Features.IsReadOnly; - public IDisposable BeginScope(TState state) - { - Scopes.Add(state); - return new Scope(); - } + public int Revision => Features.Revision; - public List Scopes { get; set; } = new List(); + public TFeature Get() => Features.Get(); - public bool IsEnabled(LogLevel logLevel) => _isEnabled; + public IEnumerator> GetEnumerator() => Features.GetEnumerator(); - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { + public void Set(TFeature instance) => Features.Set(instance); - } - - private class Scope : IDisposable - { - public void Dispose() - { - } - } - } - - private class NoopDiagnosticListener : DiagnosticListener - { - private readonly bool _isEnabled; - - public NoopDiagnosticListener(bool isEnabled = false) : base("DummyListener") - { - _isEnabled = isEnabled; - } - - public override bool IsEnabled(string name) => _isEnabled; - - public override void Write(string name, object value) - { - } - } - - private class CallbackDiagnosticListener : IObserver> - { - private readonly Action> _callback; - - public CallbackDiagnosticListener(Action> callback) - { - _callback = callback; - } - - public void OnNext(KeyValuePair value) - { - _callback(value); - } - - public void OnError(Exception error) - { - } - - public void OnCompleted() - { - } + IEnumerator IEnumerable.GetEnumerator() => Features.GetEnumerator(); } } } diff --git a/src/Hosting/Hosting/test/WebHostTests.cs b/src/Hosting/Hosting/test/WebHostTests.cs index c1499accff..f4c15ec3b7 100644 --- a/src/Hosting/Hosting/test/WebHostTests.cs +++ b/src/Hosting/Hosting/test/WebHostTests.cs @@ -198,7 +198,7 @@ namespace Microsoft.AspNetCore.Hosting } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7291")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/7291")] public async Task WebHostStopAsyncUsesDefaultTimeoutIfGivenTokenDoesNotFire() { var data = new Dictionary @@ -314,7 +314,7 @@ namespace Microsoft.AspNetCore.Hosting } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7291")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/7291")] public void WebHostApplicationLifetimeEventsOrderedCorrectlyDuringShutdown() { using (var host = CreateBuilder() diff --git a/src/Hosting/Server.Abstractions/ref/Microsoft.AspNetCore.Hosting.Server.Abstractions.netcoreapp.cs b/src/Hosting/Server.Abstractions/ref/Microsoft.AspNetCore.Hosting.Server.Abstractions.netcoreapp.cs index 184bb7353c..cf0de7f4fe 100644 --- a/src/Hosting/Server.Abstractions/ref/Microsoft.AspNetCore.Hosting.Server.Abstractions.netcoreapp.cs +++ b/src/Hosting/Server.Abstractions/ref/Microsoft.AspNetCore.Hosting.Server.Abstractions.netcoreapp.cs @@ -23,8 +23,8 @@ namespace Microsoft.AspNetCore.Hosting.Server public partial class ServerIntegratedAuth : Microsoft.AspNetCore.Hosting.Server.IServerIntegratedAuth { public ServerIntegratedAuth() { } - public string AuthenticationScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticationScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Hosting.Server.Abstractions diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/HostingModel.cs b/src/Hosting/Server.IntegrationTesting/src/Common/HostingModel.cs index 5eea2b8ce3..e1608bba80 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Common/HostingModel.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Common/HostingModel.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace Microsoft.AspNetCore.Server.IntegrationTesting diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/IWebHostExtensions.cs b/src/Hosting/Server.IntegrationTesting/src/Common/IWebHostExtensions.cs deleted file mode 100644 index 732a598ab8..0000000000 --- a/src/Hosting/Server.IntegrationTesting/src/Common/IWebHostExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.AspNetCore.Hosting.Server.Features; -using System.Linq; - -namespace Microsoft.AspNetCore.Hosting -{ - public static class IWebHostExtensions - { - public static string GetAddress(this IWebHost host) - { - return host.ServerFeatures.Get().Addresses.First(); - } - } -} diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/TestPortHelper.cs b/src/Hosting/Server.IntegrationTesting/src/Common/TestPortHelper.cs index 7129ff73d3..b8688dec04 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Common/TestPortHelper.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Common/TestPortHelper.cs @@ -56,34 +56,5 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common } } } - - private const int BasePort = 5001; - private const int MaxPort = 8000; - private static int NextPort = BasePort; - - // GetNextPort doesn't check for HttpSys urlacls. - public static int GetNextHttpSysPort(string scheme) - { - while (NextPort < MaxPort) - { - var port = NextPort++; - - using (var server = new HttpListener()) - { - server.Prefixes.Add($"{scheme}://localhost:{port}/"); - try - { - server.Start(); - server.Stop(); - return port; - } - catch (HttpListenerException) - { - } - } - } - NextPort = BasePort; - throw new Exception("Failed to locate a free port."); - } } } diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/TestUriHelper.cs b/src/Hosting/Server.IntegrationTesting/src/Common/TestUriHelper.cs index aaac5b88a7..4899fbea4f 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Common/TestUriHelper.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Common/TestUriHelper.cs @@ -1,7 +1,9 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics; + namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common { public static class TestUriHelper @@ -34,7 +36,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.Common } else if (serverType == ServerType.HttpSys) { - return new UriBuilder(scheme, "localhost", TestPortHelper.GetNextHttpSysPort(scheme)).Uri; + Debug.Assert(scheme == "http", "Https not supported"); + return new UriBuilder(scheme, "localhost", 0).Uri; } else { diff --git a/src/Hosting/Server.IntegrationTesting/src/Common/Tfm.cs b/src/Hosting/Server.IntegrationTesting/src/Common/Tfm.cs index b828a5868e..92cea4fb37 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Common/Tfm.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Common/Tfm.cs @@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting public const string NetCoreApp22 = "netcoreapp2.2"; public const string NetCoreApp30 = "netcoreapp3.0"; public const string NetCoreApp31 = "netcoreapp3.1"; + public const string NetCoreApp50 = "netcoreapp5.0"; public static bool Matches(string tfm1, string tfm2) { diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs index d5c0dc02ca..262ff80ce8 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/NginxDeployer.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; diff --git a/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs b/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs index 06923f7c46..e6e724c98c 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs +++ b/src/Hosting/Server.IntegrationTesting/src/Deployers/SelfHostDeployer.cs @@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting private static readonly Regex NowListeningRegex = new Regex(@"^\s*Now listening on: (?.*)$"); private const string ApplicationStartedMessage = "Application started. Press Ctrl+C to shut down."; - private const int RetryCount = 5; public Process HostProcess { get; private set; } public SelfHostDeployer(DeploymentParameters deploymentParameters, ILoggerFactory loggerFactory) @@ -56,33 +55,23 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting DotnetPublish(); } + var hintUrl = TestUriHelper.BuildTestUri( + DeploymentParameters.ServerType, + DeploymentParameters.Scheme, + DeploymentParameters.ApplicationBaseUriHint, + DeploymentParameters.StatusMessagesEnabled); + // Launch the host process. - for (var i = 0; i < RetryCount; i++) - { - var hintUrl = TestUriHelper.BuildTestUri( - DeploymentParameters.ServerType, - DeploymentParameters.Scheme, - DeploymentParameters.ApplicationBaseUriHint, - DeploymentParameters.StatusMessagesEnabled); - var (actualUrl, hostExitToken) = await StartSelfHostAsync(hintUrl); + var (actualUrl, hostExitToken) = await StartSelfHostAsync(hintUrl); - if (DeploymentParameters.ServerType == ServerType.HttpSys && hostExitToken.IsCancellationRequested) - { - // Retry HttpSys deployments due to port conflicts. - continue; - } + Logger.LogInformation("Application ready at URL: {appUrl}", actualUrl); - Logger.LogInformation("Application ready at URL: {appUrl}", actualUrl); - - return new DeploymentResult( - LoggerFactory, - DeploymentParameters, - applicationBaseUri: actualUrl.ToString(), - contentRoot: DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath, - hostShutdownToken: hostExitToken); - } - - throw new Exception($"Failed to start Self hosted application after {RetryCount} retries."); + return new DeploymentResult( + LoggerFactory, + DeploymentParameters, + applicationBaseUri: actualUrl.ToString(), + contentRoot: DeploymentParameters.PublishApplicationBeforeDeployment ? DeploymentParameters.PublishedApplicationRootPath : DeploymentParameters.ApplicationPath, + hostShutdownToken: hostExitToken); } } @@ -176,6 +165,8 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting Logger.LogInformation("host process ID {pid} shut down", HostProcess.Id); // If TrySetResult was called above, this will just silently fail to set the new state, which is what we want + started.TrySetException(new Exception($"Command exited unexpectedly with exit code: {HostProcess.ExitCode}")); + TriggerHostShutdown(hostExitTokenSource); }; @@ -187,6 +178,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting { Logger.LogError("Error occurred while starting the process. Exception: {exception}", ex.ToString()); } + if (HostProcess.HasExited) { Logger.LogError("Host process {processName} {pid} exited with code {exitCode} or failed to start.", startInfo.FileName, HostProcess.Id, HostProcess.ExitCode); diff --git a/src/Hosting/Server.IntegrationTesting/src/Microsoft.AspNetCore.Server.IntegrationTesting.csproj b/src/Hosting/Server.IntegrationTesting/src/Microsoft.AspNetCore.Server.IntegrationTesting.csproj index 8edf4ff3f0..ba625f4332 100644 --- a/src/Hosting/Server.IntegrationTesting/src/Microsoft.AspNetCore.Server.IntegrationTesting.csproj +++ b/src/Hosting/Server.IntegrationTesting/src/Microsoft.AspNetCore.Server.IntegrationTesting.csproj @@ -1,4 +1,4 @@ - + ASP.NET Core helpers to deploy applications to IIS Express, IIS, WebListener and Kestrel for testing. @@ -19,7 +19,6 @@ - diff --git a/src/Hosting/TestHost/ref/Microsoft.AspNetCore.TestHost.netcoreapp.cs b/src/Hosting/TestHost/ref/Microsoft.AspNetCore.TestHost.netcoreapp.cs index ed7536b490..6f94aa576c 100644 --- a/src/Hosting/TestHost/ref/Microsoft.AspNetCore.TestHost.netcoreapp.cs +++ b/src/Hosting/TestHost/ref/Microsoft.AspNetCore.TestHost.netcoreapp.cs @@ -17,12 +17,12 @@ namespace Microsoft.AspNetCore.TestHost public partial class HttpResetTestException : System.Exception { public HttpResetTestException(int errorCode) { } - public int ErrorCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int ErrorCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class RequestBuilder { public RequestBuilder(Microsoft.AspNetCore.TestHost.TestServer server, string path) { } - public Microsoft.AspNetCore.TestHost.TestServer TestServer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.TestHost.TestServer TestServer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.TestHost.RequestBuilder AddHeader(string name, string value) { throw null; } public Microsoft.AspNetCore.TestHost.RequestBuilder And(System.Action configure) { throw null; } public System.Threading.Tasks.Task GetAsync() { throw null; } @@ -35,12 +35,12 @@ namespace Microsoft.AspNetCore.TestHost public TestServer(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder, Microsoft.AspNetCore.Http.Features.IFeatureCollection featureCollection) { } public TestServer(System.IServiceProvider services) { } public TestServer(System.IServiceProvider services, Microsoft.AspNetCore.Http.Features.IFeatureCollection featureCollection) { } - public bool AllowSynchronousIO { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Uri BaseAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AllowSynchronousIO { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Uri BaseAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Hosting.IWebHost Host { get { throw null; } } - public bool PreserveExecutionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.IServiceProvider Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool PreserveExecutionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.IServiceProvider Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Net.Http.HttpClient CreateClient() { throw null; } public System.Net.Http.HttpMessageHandler CreateHandler() { throw null; } public Microsoft.AspNetCore.TestHost.RequestBuilder CreateRequest(string path) { throw null; } @@ -69,8 +69,8 @@ namespace Microsoft.AspNetCore.TestHost public partial class WebSocketClient { internal WebSocketClient() { } - public System.Action ConfigureRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList SubProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Action ConfigureRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList SubProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task ConnectAsync(System.Uri uri, System.Threading.CancellationToken cancellationToken) { throw null; } } diff --git a/src/Hosting/TestHost/src/ClientHandler.cs b/src/Hosting/TestHost/src/ClientHandler.cs index 86a425465e..06f0189aea 100644 --- a/src/Hosting/TestHost/src/ClientHandler.cs +++ b/src/Hosting/TestHost/src/ClientHandler.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.TestHost { @@ -111,7 +112,15 @@ namespace Microsoft.AspNetCore.TestHost foreach (var header in request.Headers) { - req.Headers.Append(header.Key, header.Value.ToArray()); + // User-Agent is a space delineated single line header but HttpRequestHeaders parses it as multiple elements. + if (string.Equals(header.Key, HeaderNames.UserAgent, StringComparison.OrdinalIgnoreCase)) + { + req.Headers.Append(header.Key, string.Join(" ", header.Value)); + } + else + { + req.Headers.Append(header.Key, header.Value.ToArray()); + } } if (!req.Host.HasValue) @@ -163,6 +172,7 @@ namespace Microsoft.AspNetCore.TestHost response.StatusCode = (HttpStatusCode)httpContext.Response.StatusCode; response.ReasonPhrase = httpContext.Features.Get().ReasonPhrase; response.RequestMessage = request; + response.Version = request.Version; response.Content = new StreamContent(httpContext.Response.Body); diff --git a/src/Hosting/TestHost/src/HttpContextBuilder.cs b/src/Hosting/TestHost/src/HttpContextBuilder.cs index aab30590aa..7048e786b2 100644 --- a/src/Hosting/TestHost/src/HttpContextBuilder.cs +++ b/src/Hosting/TestHost/src/HttpContextBuilder.cs @@ -160,7 +160,17 @@ namespace Microsoft.AspNetCore.TestHost private async Task CompleteRequestAsync() { - if (!_requestPipe.Reader.TryRead(out var result) || !result.IsCompleted) + bool requestBodyInProgress; + try + { + requestBodyInProgress = !_requestPipe.Reader.TryRead(out var result) || !result.IsCompleted; + } + catch (Exception ex) + { + throw new InvalidOperationException("An error occurred when completing the request. Request delegate may have finished while there is a pending read of the request body.", ex); + } + + if (requestBodyInProgress) { // If request is still in progress then abort it. CancelRequestBody(); diff --git a/src/Hosting/TestHost/src/WebSocketClient.cs b/src/Hosting/TestHost/src/WebSocketClient.cs index 7cf116cd7a..cfb6ceda32 100644 --- a/src/Hosting/TestHost/src/WebSocketClient.cs +++ b/src/Hosting/TestHost/src/WebSocketClient.cs @@ -4,12 +4,14 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net.WebSockets; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.TestHost { @@ -72,10 +74,15 @@ namespace Microsoft.AspNetCore.TestHost request.PathBase = _pathBase; } request.QueryString = QueryString.FromUriComponent(uri); - request.Headers.Add("Connection", new string[] { "Upgrade" }); - request.Headers.Add("Upgrade", new string[] { "websocket" }); - request.Headers.Add("Sec-WebSocket-Version", new string[] { "13" }); - request.Headers.Add("Sec-WebSocket-Key", new string[] { CreateRequestKey() }); + request.Headers.Add(HeaderNames.Connection, new string[] { "Upgrade" }); + request.Headers.Add(HeaderNames.Upgrade, new string[] { "websocket" }); + request.Headers.Add(HeaderNames.SecWebSocketVersion, new string[] { "13" }); + request.Headers.Add(HeaderNames.SecWebSocketKey, new string[] { CreateRequestKey() }); + if (SubProtocols.Any()) + { + request.Headers.Add(HeaderNames.SecWebSocketProtocol, SubProtocols.ToArray()); + } + request.Body = Stream.Null; // WebSocket @@ -102,8 +109,7 @@ namespace Microsoft.AspNetCore.TestHost private string CreateRequestKey() { byte[] data = new byte[16]; - var rng = RandomNumberGenerator.Create(); - rng.GetBytes(data); + RandomNumberGenerator.Fill(data); return Convert.ToBase64String(data); } diff --git a/src/Hosting/TestHost/test/ClientHandlerTests.cs b/src/Hosting/TestHost/test/ClientHandlerTests.cs index 521a056e15..9013b07f44 100644 --- a/src/Hosting/TestHost/test/ClientHandlerTests.cs +++ b/src/Hosting/TestHost/test/ClientHandlerTests.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; using Xunit; namespace Microsoft.AspNetCore.TestHost @@ -85,6 +86,23 @@ namespace Microsoft.AspNetCore.TestHost return httpClient.GetAsync("https://example.com/"); } + [Fact] + public Task UserAgentHeaderWorks() + { + var userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"; + var handler = new ClientHandler(new PathString(""), new DummyApplication(context => + { + var actualResult = context.Request.Headers[HeaderNames.UserAgent]; + Assert.Equal(userAgent, actualResult); + + return Task.CompletedTask; + })); + var httpClient = new HttpClient(handler); + httpClient.DefaultRequestHeaders.Add(HeaderNames.UserAgent, userAgent); + + return httpClient.GetAsync("http://example.com"); + } + [Fact] public async Task ServerTrailersSetOnResponseAfterContentRead() { diff --git a/src/Hosting/TestHost/test/HttpContextBuilderTests.cs b/src/Hosting/TestHost/test/HttpContextBuilderTests.cs index b4731e1572..cc4570b0e3 100644 --- a/src/Hosting/TestHost/test/HttpContextBuilderTests.cs +++ b/src/Hosting/TestHost/test/HttpContextBuilderTests.cs @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; using Xunit; namespace Microsoft.AspNetCore.TestHost @@ -47,6 +48,22 @@ namespace Microsoft.AspNetCore.TestHost Assert.Null(context.Features.Get().ReasonPhrase); } + [Fact] + public async Task UserAgentHeaderWorks() + { + var userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0"; + var builder = new WebHostBuilder().Configure(app => { }); + var server = new TestServer(builder); + server.BaseAddress = new Uri("https://example.com/"); + var context = await server.SendAsync(c => + { + c.Request.Headers[HeaderNames.UserAgent] = userAgent; + }); + + var actualResult = context.Request.Headers[HeaderNames.UserAgent]; + Assert.Equal(userAgent, actualResult); + } + [Fact] public async Task SingleSlashNotMovedToPathBase() { diff --git a/src/Hosting/TestHost/test/TestClientTests.cs b/src/Hosting/TestHost/test/TestClientTests.cs index 9ae6caebfe..8c1ac8a2ce 100644 --- a/src/Hosting/TestHost/test/TestClientTests.cs +++ b/src/Hosting/TestHost/test/TestClientTests.cs @@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; using Xunit; namespace Microsoft.AspNetCore.TestHost @@ -384,6 +385,54 @@ namespace Microsoft.AspNetCore.TestHost await writeTask; } + [Fact] + public async Task ClientStreaming_ResponseCompletesWithPendingRead_ThrowError() + { + // Arrange + var requestStreamTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + RequestDelegate appDelegate = async ctx => + { + var pendingReadTask = ctx.Request.Body.ReadAsync(new byte[1024], 0, 1024); + ctx.Response.Headers["test-header"] = "true"; + await ctx.Response.Body.FlushAsync(); + }; + + Stream requestStream = null; + + var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate)); + var server = new TestServer(builder); + var client = server.CreateClient(); + + var httpRequest = new HttpRequestMessage(HttpMethod.Post, "http://localhost:12345"); + httpRequest.Version = new Version(2, 0); + httpRequest.Content = new PushContent(async stream => + { + requestStream = stream; + await requestStreamTcs.Task; + }); + + // Act + var response = await client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).WithTimeout(); + + var responseContent = await response.Content.ReadAsStreamAsync().WithTimeout(); + + // Assert + response.EnsureSuccessStatusCode(); + Assert.Equal("true", response.Headers.GetValues("test-header").Single()); + + // Read response + var ex = await Assert.ThrowsAsync(async () => + { + byte[] buffer = new byte[1024]; + var length = await responseContent.ReadAsync(buffer).AsTask().WithTimeout(); + }); + Assert.Equal("An error occurred when completing the request. Request delegate may have finished while there is a pending read of the request body.", ex.InnerException.Message); + + // Unblock request + requestStreamTcs.TrySetResult(null); + } + [Fact] public async Task ClientStreaming_ServerAbort() { @@ -467,6 +516,7 @@ namespace Microsoft.AspNetCore.TestHost { if (ctx.WebSockets.IsWebSocketRequest) { + Assert.False(ctx.Request.Headers.ContainsKey(HeaderNames.SecWebSocketProtocol)); var websocket = await ctx.WebSockets.AcceptWebSocketAsync(); var receiveArray = new byte[1024]; while (true) @@ -527,6 +577,58 @@ namespace Microsoft.AspNetCore.TestHost clientSocket.Dispose(); } + [Fact] + public async Task WebSocketSubProtocolsWorks() + { + // Arrange + RequestDelegate appDelegate = async ctx => + { + if (ctx.WebSockets.IsWebSocketRequest) + { + if (ctx.WebSockets.WebSocketRequestedProtocols.Contains("alpha") && + ctx.WebSockets.WebSocketRequestedProtocols.Contains("bravo")) + { + // according to rfc6455, the "server needs to include the same field and one of the selected subprotocol values" + // however, this isn't enforced by either our server or client so it's possible to accept an arbitrary protocol. + // Done here to demonstrate not "correct" behaviour, simply to show it's possible. Other clients may not allow this. + var websocket = await ctx.WebSockets.AcceptWebSocketAsync("charlie"); + await websocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Normal Closure", CancellationToken.None); + } + else + { + var subprotocols = ctx.WebSockets.WebSocketRequestedProtocols.Any() + ? string.Join(", ", ctx.WebSockets.WebSocketRequestedProtocols) + : ""; + var closeReason = "Unexpected subprotocols: " + subprotocols; + var websocket = await ctx.WebSockets.AcceptWebSocketAsync(); + await websocket.CloseAsync(WebSocketCloseStatus.InternalServerError, closeReason, CancellationToken.None); + } + } + }; + var builder = new WebHostBuilder() + .Configure(app => + { + app.Run(appDelegate); + }); + var server = new TestServer(builder); + + // Act + var client = server.CreateWebSocketClient(); + client.SubProtocols.Add("alpha"); + client.SubProtocols.Add("bravo"); + var clientSocket = await client.ConnectAsync(new Uri("wss://localhost"), CancellationToken.None); + var buffer = new byte[1024]; + var result = await clientSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); + + // Assert + Assert.Equal(WebSocketMessageType.Close, result.MessageType); + Assert.Equal("Normal Closure", result.CloseStatusDescription); + Assert.Equal(WebSocketState.CloseReceived, clientSocket.State); + Assert.Equal("charlie", clientSocket.SubProtocol); + + clientSocket.Dispose(); + } + [ConditionalFact] public async Task WebSocketAcceptThrowsWhenCancelled() { @@ -769,5 +871,48 @@ namespace Microsoft.AspNetCore.TestHost Assert.Same(value, capturedValue); } + + [Fact] + public async Task SendAsync_Default_Protocol11() + { + // Arrange + var expected = "GET Response"; + RequestDelegate appDelegate = ctx => + ctx.Response.WriteAsync(expected); + var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate)); + var server = new TestServer(builder); + var client = server.CreateClient(); + var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:12345"); + + // Act + var message = await client.SendAsync(request); + var actual = await message.Content.ReadAsStringAsync(); + + // Assert + Assert.Equal(expected, actual); + Assert.Equal(new Version(1, 1), message.Version); + } + + [Fact] + public async Task SendAsync_ExplicitlySet_Protocol20() + { + // Arrange + var expected = "GET Response"; + RequestDelegate appDelegate = ctx => + ctx.Response.WriteAsync(expected); + var builder = new WebHostBuilder().Configure(app => app.Run(appDelegate)); + var server = new TestServer(builder); + var client = server.CreateClient(); + var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:12345"); + request.Version = new Version(2, 0); + + // Act + var message = await client.SendAsync(request); + var actual = await message.Content.ReadAsStringAsync(); + + // Assert + Assert.Equal(expected, actual); + Assert.Equal(new Version(2, 0), message.Version); + } } } diff --git a/src/Hosting/build.cmd b/src/Hosting/build.cmd deleted file mode 100644 index 2406296662..0000000000 --- a/src/Hosting/build.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@ECHO OFF -SET RepoRoot=%~dp0..\.. -%RepoRoot%\build.cmd -projects %~dp0**\*.*proj %* diff --git a/src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj b/src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj index 75a2f330f7..b63810b68d 100644 --- a/src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj +++ b/src/Hosting/test/FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.csproj @@ -4,7 +4,7 @@ $(DefaultNetCoreTargetFramework) - + false diff --git a/src/Hosting/test/FunctionalTests/ShutdownTests.cs b/src/Hosting/test/FunctionalTests/ShutdownTests.cs index 246a9abbea..96ba91bcaa 100644 --- a/src/Hosting/test/FunctionalTests/ShutdownTests.cs +++ b/src/Hosting/test/FunctionalTests/ShutdownTests.cs @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests { var logger = loggerFactory.CreateLogger(testName); -// https://github.com/aspnet/AspNetCore/issues/8247 +// https://github.com/dotnet/aspnetcore/issues/8247 #pragma warning disable 0618 var applicationPath = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("Hosting"), "test", "testassets", "Microsoft.AspNetCore.Hosting.TestSites"); @@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests RuntimeArchitecture.x64) { EnvironmentName = "Shutdown", - TargetFramework = Tfm.NetCoreApp31, + TargetFramework = Tfm.NetCoreApp50, ApplicationType = ApplicationType.Portable, PublishApplicationBeforeDeployment = true, StatusMessagesEnabled = false diff --git a/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs b/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs index 5d5044eacc..27603a86a5 100644 --- a/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs +++ b/src/Hosting/test/FunctionalTests/WebHostBuilderTests.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests public WebHostBuilderTests(ITestOutputHelper output) : base(output) { } public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.Kestrel) - .WithTfms(Tfm.NetCoreApp31); + .WithTfms(Tfm.NetCoreApp50); [ConditionalTheory] [MemberData(nameof(TestVariants))] @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Hosting.FunctionalTests { var logger = loggerFactory.CreateLogger(nameof(InjectedStartup_DefaultApplicationNameIsEntryAssembly)); -// https://github.com/aspnet/AspNetCore/issues/8247 +// https://github.com/dotnet/aspnetcore/issues/8247 #pragma warning disable 0618 var applicationPath = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("Hosting"), "test", "testassets", "IStartupInjectionAssemblyName"); #pragma warning restore 0618 diff --git a/src/Html/Abstractions/ref/Microsoft.AspNetCore.Html.Abstractions.netcoreapp.cs b/src/Html/Abstractions/ref/Microsoft.AspNetCore.Html.Abstractions.netcoreapp.cs index 2c4b056743..206b2611d1 100644 --- a/src/Html/Abstractions/ref/Microsoft.AspNetCore.Html.Abstractions.netcoreapp.cs +++ b/src/Html/Abstractions/ref/Microsoft.AspNetCore.Html.Abstractions.netcoreapp.cs @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Html public static readonly Microsoft.AspNetCore.Html.HtmlString Empty; public static readonly Microsoft.AspNetCore.Html.HtmlString NewLine; public HtmlString(string value) { } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string ToString() { throw null; } public void WriteTo(System.IO.TextWriter writer, System.Text.Encodings.Web.HtmlEncoder encoder) { } } diff --git a/src/Http/Authentication.Abstractions/ref/Microsoft.AspNetCore.Authentication.Abstractions.netcoreapp.cs b/src/Http/Authentication.Abstractions/ref/Microsoft.AspNetCore.Authentication.Abstractions.netcoreapp.cs index dd9628c89a..4027259f90 100644 --- a/src/Http/Authentication.Abstractions/ref/Microsoft.AspNetCore.Authentication.Abstractions.netcoreapp.cs +++ b/src/Http/Authentication.Abstractions/ref/Microsoft.AspNetCore.Authentication.Abstractions.netcoreapp.cs @@ -6,12 +6,12 @@ namespace Microsoft.AspNetCore.Authentication public partial class AuthenticateResult { protected AuthenticateResult() { } - public System.Exception Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public bool None { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public System.Exception Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public bool None { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public System.Security.Claims.ClaimsPrincipal Principal { get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public bool Succeeded { get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationTicket Ticket { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationTicket Ticket { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Authentication.AuthenticateResult Fail(System.Exception failure) { throw null; } public static Microsoft.AspNetCore.Authentication.AuthenticateResult Fail(System.Exception failure, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { throw null; } public static Microsoft.AspNetCore.Authentication.AuthenticateResult Fail(string failureMessage) { throw null; } @@ -45,14 +45,14 @@ namespace Microsoft.AspNetCore.Authentication public partial class AuthenticationOptions { public AuthenticationOptions() { } - public string DefaultAuthenticateScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DefaultChallengeScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DefaultForbidScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DefaultScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DefaultSignInScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DefaultSignOutScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireAuthenticatedSignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary SchemeMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DefaultAuthenticateScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DefaultChallengeScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DefaultForbidScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DefaultScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DefaultSignInScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DefaultSignOutScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireAuthenticatedSignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary SchemeMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IEnumerable Schemes { get { throw null; } } public void AddScheme(string name, System.Action configureBuilder) { } public void AddScheme(string name, string displayName) where THandler : Microsoft.AspNetCore.Authentication.IAuthenticationHandler { } @@ -66,8 +66,8 @@ namespace Microsoft.AspNetCore.Authentication public System.DateTimeOffset? ExpiresUtc { get { throw null; } set { } } public bool IsPersistent { get { throw null; } set { } } public System.DateTimeOffset? IssuedUtc { get { throw null; } set { } } - public System.Collections.Generic.IDictionary Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string RedirectUri { get { throw null; } set { } } protected bool? GetBool(string key) { throw null; } protected System.DateTimeOffset? GetDateTimeOffset(string key) { throw null; } @@ -81,31 +81,31 @@ namespace Microsoft.AspNetCore.Authentication public partial class AuthenticationScheme { public AuthenticationScheme(string name, string displayName, System.Type handlerType) { } - public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type HandlerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type HandlerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class AuthenticationSchemeBuilder { public AuthenticationSchemeBuilder(string name) { } - public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type HandlerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type HandlerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Authentication.AuthenticationScheme Build() { throw null; } } public partial class AuthenticationTicket { public AuthenticationTicket(System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, string authenticationScheme) { } public AuthenticationTicket(System.Security.Claims.ClaimsPrincipal principal, string authenticationScheme) { } - public string AuthenticationScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AuthenticationScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class AuthenticationToken { public AuthenticationToken() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class AuthenticationTokenExtensions { @@ -149,6 +149,7 @@ namespace Microsoft.AspNetCore.Authentication System.Threading.Tasks.Task> GetRequestHandlerSchemesAsync(); System.Threading.Tasks.Task GetSchemeAsync(string name); void RemoveScheme(string name); + bool TryAddScheme(Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme) { throw null; } } public partial interface IAuthenticationService { diff --git a/src/Http/Authentication.Abstractions/src/IAuthenticationRequestHandler.cs b/src/Http/Authentication.Abstractions/src/IAuthenticationRequestHandler.cs index d2822cdc88..d0013725c6 100644 --- a/src/Http/Authentication.Abstractions/src/IAuthenticationRequestHandler.cs +++ b/src/Http/Authentication.Abstractions/src/IAuthenticationRequestHandler.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Authentication /// /// Returns true if request processing should stop. /// - /// true if request processing should stop. + /// if request processing should stop. Task HandleRequestAsync(); } diff --git a/src/Http/Authentication.Abstractions/src/IAuthenticationSchemeProvider.cs b/src/Http/Authentication.Abstractions/src/IAuthenticationSchemeProvider.cs index 3d2584fca8..d0f54d74d0 100644 --- a/src/Http/Authentication.Abstractions/src/IAuthenticationSchemeProvider.cs +++ b/src/Http/Authentication.Abstractions/src/IAuthenticationSchemeProvider.cs @@ -71,6 +71,23 @@ namespace Microsoft.AspNetCore.Authentication /// The scheme. void AddScheme(AuthenticationScheme scheme); + /// + /// Registers a scheme for use by . + /// + /// The scheme. + /// true if the scheme was added successfully. + bool TryAddScheme(AuthenticationScheme scheme) + { + try + { + AddScheme(scheme); + return true; + } + catch { + return false; + } + } + /// /// Removes a scheme, preventing it from being used by . /// diff --git a/src/Http/Authentication.Core/ref/Microsoft.AspNetCore.Authentication.Core.netcoreapp.cs b/src/Http/Authentication.Core/ref/Microsoft.AspNetCore.Authentication.Core.netcoreapp.cs index f12e27bcf2..590d651d41 100644 --- a/src/Http/Authentication.Core/ref/Microsoft.AspNetCore.Authentication.Core.netcoreapp.cs +++ b/src/Http/Authentication.Core/ref/Microsoft.AspNetCore.Authentication.Core.netcoreapp.cs @@ -6,13 +6,13 @@ namespace Microsoft.AspNetCore.Authentication public partial class AuthenticationFeature : Microsoft.AspNetCore.Authentication.IAuthenticationFeature { public AuthenticationFeature() { } - public Microsoft.AspNetCore.Http.PathString OriginalPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString OriginalPathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.PathString OriginalPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString OriginalPathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class AuthenticationHandlerProvider : Microsoft.AspNetCore.Authentication.IAuthenticationHandlerProvider { public AuthenticationHandlerProvider(Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider schemes) { } - public Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider Schemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider Schemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task GetHandlerAsync(Microsoft.AspNetCore.Http.HttpContext context, string authenticationScheme) { throw null; } } @@ -30,14 +30,15 @@ namespace Microsoft.AspNetCore.Authentication public virtual System.Threading.Tasks.Task> GetRequestHandlerSchemesAsync() { throw null; } public virtual System.Threading.Tasks.Task GetSchemeAsync(string name) { throw null; } public virtual void RemoveScheme(string name) { } + public virtual bool TryAddScheme(Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme) { throw null; } } public partial class AuthenticationService : Microsoft.AspNetCore.Authentication.IAuthenticationService { public AuthenticationService(Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider schemes, Microsoft.AspNetCore.Authentication.IAuthenticationHandlerProvider handlers, Microsoft.AspNetCore.Authentication.IClaimsTransformation transform, Microsoft.Extensions.Options.IOptions options) { } - public Microsoft.AspNetCore.Authentication.IAuthenticationHandlerProvider Handlers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider Schemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authentication.IClaimsTransformation Transform { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.IAuthenticationHandlerProvider Handlers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authentication.AuthenticationOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider Schemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authentication.IClaimsTransformation Transform { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task AuthenticateAsync(Microsoft.AspNetCore.Http.HttpContext context, string scheme) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] diff --git a/src/Http/Authentication.Core/src/AuthenticationSchemeProvider.cs b/src/Http/Authentication.Core/src/AuthenticationSchemeProvider.cs index a7b913b1b2..4f181081f2 100644 --- a/src/Http/Authentication.Core/src/AuthenticationSchemeProvider.cs +++ b/src/Http/Authentication.Core/src/AuthenticationSchemeProvider.cs @@ -133,17 +133,18 @@ namespace Microsoft.AspNetCore.Authentication /// Registers a scheme for use by . /// /// The scheme. - public virtual void AddScheme(AuthenticationScheme scheme) + /// true if the scheme was added successfully. + public virtual bool TryAddScheme(AuthenticationScheme scheme) { if (_schemes.ContainsKey(scheme.Name)) { - throw new InvalidOperationException("Scheme already exists: " + scheme.Name); + return false; } lock (_lock) { if (_schemes.ContainsKey(scheme.Name)) { - throw new InvalidOperationException("Scheme already exists: " + scheme.Name); + return false; } if (typeof(IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType)) { @@ -152,6 +153,26 @@ namespace Microsoft.AspNetCore.Authentication } _schemes[scheme.Name] = scheme; _schemesCopy = _schemes.Values.ToArray(); + return true; + } + } + + /// + /// Registers a scheme for use by . + /// + /// The scheme. + public virtual void AddScheme(AuthenticationScheme scheme) + { + if (_schemes.ContainsKey(scheme.Name)) + { + throw new InvalidOperationException("Scheme already exists: " + scheme.Name); + } + lock (_lock) + { + if (!TryAddScheme(scheme)) + { + throw new InvalidOperationException("Scheme already exists: " + scheme.Name); + } } } diff --git a/src/Http/Authentication.Core/src/AuthenticationService.cs b/src/Http/Authentication.Core/src/AuthenticationService.cs index 7efce69ce8..de63980c4a 100644 --- a/src/Http/Authentication.Core/src/AuthenticationService.cs +++ b/src/Http/Authentication.Core/src/AuthenticationService.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; @@ -15,6 +16,8 @@ namespace Microsoft.AspNetCore.Authentication /// public class AuthenticationService : IAuthenticationService { + private HashSet _transformCache; + /// /// Constructor. /// @@ -77,8 +80,20 @@ namespace Microsoft.AspNetCore.Authentication var result = await handler.AuthenticateAsync(); if (result != null && result.Succeeded) { - var transformed = await Transform.TransformAsync(result.Principal); - return AuthenticateResult.Success(new AuthenticationTicket(transformed, result.Properties, result.Ticket.AuthenticationScheme)); + var principal = result.Principal; + var doTransform = true; + _transformCache ??= new HashSet(); + if (_transformCache.Contains(principal)) + { + doTransform = false; + } + + if (doTransform) + { + principal = await Transform.TransformAsync(principal); + _transformCache.Add(principal); + } + return AuthenticateResult.Success(new AuthenticationTicket(principal, result.Properties, result.Ticket.AuthenticationScheme)); } return result; } @@ -253,7 +268,7 @@ namespace Microsoft.AspNetCore.Authentication var schemes = await GetAllSignInSchemeNames(); // CookieAuth is the only implementation of sign-in. - var footer = $" Did you forget to call AddAuthentication().AddCookies(\"{scheme}\",...)?"; + var footer = $" Did you forget to call AddAuthentication().AddCookie(\"{scheme}\",...)?"; if (string.IsNullOrEmpty(schemes)) { @@ -275,7 +290,7 @@ namespace Microsoft.AspNetCore.Authentication { // CookieAuth is the only implementation of sign-in. return new InvalidOperationException(mismatchError - + $"Did you forget to call AddAuthentication().AddCookies(\"Cookies\") and SignInAsync(\"Cookies\",...)?"); + + $"Did you forget to call AddAuthentication().AddCookie(\"Cookies\") and SignInAsync(\"Cookies\",...)?"); } return new InvalidOperationException(mismatchError + $"The registered sign-in schemes are: {schemes}."); @@ -292,7 +307,7 @@ namespace Microsoft.AspNetCore.Authentication { var schemes = await GetAllSignOutSchemeNames(); - var footer = $" Did you forget to call AddAuthentication().AddCookies(\"{scheme}\",...)?"; + var footer = $" Did you forget to call AddAuthentication().AddCookie(\"{scheme}\",...)?"; if (string.IsNullOrEmpty(schemes)) { @@ -314,7 +329,7 @@ namespace Microsoft.AspNetCore.Authentication { // CookieAuth is the most common implementation of sign-out, but OpenIdConnect and WsFederation also support it. return new InvalidOperationException(mismatchError - + $"Did you forget to call AddAuthentication().AddCookies(\"Cookies\") and {nameof(SignOutAsync)}(\"Cookies\",...)?"); + + $"Did you forget to call AddAuthentication().AddCookie(\"Cookies\") and {nameof(SignOutAsync)}(\"Cookies\",...)?"); } return new InvalidOperationException(mismatchError + $"The registered sign-out schemes are: {schemes}."); diff --git a/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs b/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs index 84db381ce4..c8a8056077 100644 --- a/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs +++ b/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -298,4 +298,4 @@ namespace Microsoft.AspNetCore.Authentication.Core.Test } } } -} +} \ No newline at end of file diff --git a/src/Http/Authentication.Core/test/AuthenticationSchemeProviderTests.cs b/src/Http/Authentication.Core/test/AuthenticationSchemeProviderTests.cs index 82602000aa..f422ee885d 100644 --- a/src/Http/Authentication.Core/test/AuthenticationSchemeProviderTests.cs +++ b/src/Http/Authentication.Core/test/AuthenticationSchemeProviderTests.cs @@ -11,7 +11,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Xunit; -namespace Microsoft.AspNetCore.Authentication +namespace Microsoft.AspNetCore.Authentication.Core.Test { public class AuthenticationSchemeProviderTests { @@ -133,6 +133,23 @@ namespace Microsoft.AspNetCore.Authentication Assert.Contains("Scheme already exists: signin", error.Message); } + [Fact] + public void CanSafelyTryAddSchemes() + { + var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o => + { + }).BuildServiceProvider(); + + var o = services.GetRequiredService(); + Assert.True(o.TryAddScheme(new AuthenticationScheme("signin", "whatever", typeof(Handler)))); + Assert.True(o.TryAddScheme(new AuthenticationScheme("signin2", "whatever", typeof(Handler)))); + Assert.False(o.TryAddScheme(new AuthenticationScheme("signin", "whatever", typeof(Handler)))); + Assert.True(o.TryAddScheme(new AuthenticationScheme("signin3", "whatever", typeof(Handler)))); + Assert.False(o.TryAddScheme(new AuthenticationScheme("signin2", "whatever", typeof(Handler)))); + o.RemoveScheme("signin2"); + Assert.True(o.TryAddScheme(new AuthenticationScheme("signin2", "whatever", typeof(Handler)))); + } + [Fact] public async Task LookupUsesProvidedStringComparer() { diff --git a/src/Http/Authentication.Core/test/AuthenticationServiceTests.cs b/src/Http/Authentication.Core/test/AuthenticationServiceTests.cs index b62db22077..6134ca9172 100644 --- a/src/Http/Authentication.Core/test/AuthenticationServiceTests.cs +++ b/src/Http/Authentication.Core/test/AuthenticationServiceTests.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace Microsoft.AspNetCore.Authentication +namespace Microsoft.AspNetCore.Authentication.Core.Test { public class AuthenticationServiceTests { @@ -27,6 +27,30 @@ namespace Microsoft.AspNetCore.Authentication Assert.Contains("base", ex.Message); } + [Fact] + public async Task CustomHandlersAuthenticateRunsClaimsTransformationEveryTime() + { + var transform = new RunOnce(); + var services = new ServiceCollection().AddOptions().AddAuthenticationCore(o => + { + o.AddScheme("base", "whatever"); + }) + .AddSingleton(transform) + .BuildServiceProvider(); + var context = new DefaultHttpContext(); + context.RequestServices = services; + + // Because base handler returns a different principal per call, its run multiple times + await context.AuthenticateAsync("base"); + Assert.Equal(1, transform.Ran); + + await context.AuthenticateAsync("base"); + Assert.Equal(2, transform.Ran); + + await context.AuthenticateAsync("base"); + Assert.Equal(3, transform.Ran); + } + [Fact] public async Task ChallengeThrowsForSchemeMismatch() { @@ -219,12 +243,25 @@ namespace Microsoft.AspNetCore.Authentication await context.ForbidAsync(); } + private class RunOnce : IClaimsTransformation + { + public int Ran = 0; + public Task TransformAsync(ClaimsPrincipal principal) + { + Ran++; + return Task.FromResult(new ClaimsPrincipal()); + } + } private class BaseHandler : IAuthenticationHandler { public Task AuthenticateAsync() { - return Task.FromResult(AuthenticateResult.NoResult()); + return Task.FromResult(AuthenticateResult.Success( + new AuthenticationTicket( + new ClaimsPrincipal(new ClaimsIdentity("whatever")), + new AuthenticationProperties(), + "whatever"))); } public Task ChallengeAsync(AuthenticationProperties properties) diff --git a/src/Http/Authentication.Core/test/TokenExtensionTests.cs b/src/Http/Authentication.Core/test/TokenExtensionTests.cs index 7215d526e9..49f47cf45f 100644 --- a/src/Http/Authentication.Core/test/TokenExtensionTests.cs +++ b/src/Http/Authentication.Core/test/TokenExtensionTests.cs @@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Xunit; -namespace Microsoft.AspNetCore.Authentication +namespace Microsoft.AspNetCore.Authentication.Core.Test { public class TokenExtensionTests { diff --git a/src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs b/src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs index a730eadf21..41d44ad26d 100644 --- a/src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs +++ b/src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs @@ -133,6 +133,7 @@ namespace Microsoft.Net.Http.Headers public static readonly string AccessControlRequestMethod; public static readonly string Age; public static readonly string Allow; + public static readonly string AltSvc; public static readonly string Authority; public static readonly string Authorization; public static readonly string CacheControl; @@ -325,14 +326,14 @@ namespace Microsoft.Net.Http.Headers { public SetCookieHeaderValue(Microsoft.Extensions.Primitives.StringSegment name) { } public SetCookieHeaderValue(Microsoft.Extensions.Primitives.StringSegment name, Microsoft.Extensions.Primitives.StringSegment value) { } - public Microsoft.Extensions.Primitives.StringSegment Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.Primitives.StringSegment Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.Extensions.Primitives.StringSegment Name { get { throw null; } set { } } - public Microsoft.Extensions.Primitives.StringSegment Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Net.Http.Headers.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.Primitives.StringSegment Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Net.Http.Headers.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.Extensions.Primitives.StringSegment Value { get { throw null; } set { } } public void AppendToStringBuilder(System.Text.StringBuilder builder) { } public override bool Equals(object obj) { throw null; } diff --git a/src/Http/Headers/src/EntityTagHeaderValue.cs b/src/Http/Headers/src/EntityTagHeaderValue.cs index e46cee3a34..9b3a37136b 100644 --- a/src/Http/Headers/src/EntityTagHeaderValue.cs +++ b/src/Http/Headers/src/EntityTagHeaderValue.cs @@ -53,7 +53,7 @@ namespace Microsoft.Net.Http.Headers (length != tag.Length)) { // Note that we don't allow 'W/' prefixes for weak ETags in the 'tag' parameter. If the user wants to - // add a weak ETag, he can set 'isWeak' to true. + // add a weak ETag, they can set 'isWeak' to true. throw new FormatException("Invalid ETag name"); } diff --git a/src/Http/Headers/src/HeaderNames.cs b/src/Http/Headers/src/HeaderNames.cs index 602916254a..368cd8be46 100644 --- a/src/Http/Headers/src/HeaderNames.cs +++ b/src/Http/Headers/src/HeaderNames.cs @@ -21,6 +21,7 @@ namespace Microsoft.Net.Http.Headers public static readonly string AccessControlRequestMethod = "Access-Control-Request-Method"; public static readonly string Age = "Age"; public static readonly string Allow = "Allow"; + public static readonly string AltSvc = "Alt-Svc"; public static readonly string Authority = ":authority"; public static readonly string Authorization = "Authorization"; public static readonly string CacheControl = "Cache-Control"; diff --git a/src/Http/Headers/src/HeaderUtilities.cs b/src/Http/Headers/src/HeaderUtilities.cs index 0d193b4e61..ff5bb5400c 100644 --- a/src/Http/Headers/src/HeaderUtilities.cs +++ b/src/Http/Headers/src/HeaderUtilities.cs @@ -26,7 +26,7 @@ namespace Microsoft.Net.Http.Headers { // Note that even if we check the value here, we can't prevent a user from adding an invalid quality // value using Parameters.Add(). Even if we would prevent the user from adding an invalid value - // using Parameters.Add() he could always add invalid values using HttpHeaders.AddWithoutValidation(). + // using Parameters.Add() they could always add invalid values using HttpHeaders.AddWithoutValidation(). // So this check is really for convenience to show users that they're trying to add an invalid // value. if ((value < 0) || (value > 1)) @@ -230,8 +230,8 @@ namespace Microsoft.Net.Http.Headers /// any value originally supplied in result will be overwritten. /// /// - /// true if is found and successfully parsed; otherwise, - /// false. + /// if is found and successfully parsed; otherwise, + /// . /// // e.g. { "headerValue=10, targetHeaderValue=30" } public static bool TryParseSeconds(StringValues headerValues, string targetValue, out TimeSpan? value) @@ -286,8 +286,8 @@ namespace Microsoft.Net.Http.Headers /// The target cache control directives to look for. /// /// - /// true if is contained in ; - /// otherwise, false. + /// if is contained in ; + /// otherwise, . /// public static bool ContainsCacheDirective(StringValues cacheControlDirectives, string targetDirectives) { @@ -367,7 +367,7 @@ namespace Microsoft.Net.Http.Headers /// greater than Int64.MaxValue. This parameter is passed uninitialized; any value originally supplied in /// result will be overwritten. /// - /// true if parsing succeeded; otherwise, false. + /// if parsing succeeded; otherwise, . public static unsafe bool TryParseNonNegativeInt32(StringSegment value, out int result) { if (string.IsNullOrEmpty(value.Buffer) || value.Length == 0) @@ -418,7 +418,7 @@ namespace Microsoft.Net.Http.Headers /// represents a number greater than Int64.MaxValue. This parameter is passed uninitialized; any value /// originally supplied in result will be overwritten. /// - /// true if parsing succeeded; otherwise, false. + /// if parsing succeeded; otherwise, . public static unsafe bool TryParseNonNegativeInt64(StringSegment value, out long result) { if (string.IsNullOrEmpty(value.Buffer) || value.Length == 0) diff --git a/src/Http/Headers/src/SetCookieHeaderValue.cs b/src/Http/Headers/src/SetCookieHeaderValue.cs index 3a5b217d6c..cdf12381aa 100644 --- a/src/Http/Headers/src/SetCookieHeaderValue.cs +++ b/src/Http/Headers/src/SetCookieHeaderValue.cs @@ -24,10 +24,6 @@ namespace Microsoft.Net.Http.Headers private static readonly string SameSiteLaxToken = SameSiteMode.Lax.ToString().ToLower(); private static readonly string SameSiteStrictToken = SameSiteMode.Strict.ToString().ToLower(); - // True (old): https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-3.1 - // False (new): https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.1 - internal static bool SuppressSameSiteNone; - private const string HttpOnlyToken = "httponly"; private const string SeparatorToken = "; "; private const string EqualsToken = "="; @@ -42,14 +38,6 @@ namespace Microsoft.Net.Http.Headers private StringSegment _name; private StringSegment _value; - static SetCookieHeaderValue() - { - if (AppContext.TryGetSwitch("Microsoft.AspNetCore.SuppressSameSiteNone", out var enabled)) - { - SuppressSameSiteNone = enabled; - } - } - private SetCookieHeaderValue() { // Used by the parser to create a new instance of this type. @@ -106,7 +94,7 @@ namespace Microsoft.Net.Http.Headers public bool Secure { get; set; } - public SameSiteMode SameSite { get; set; } = SuppressSameSiteNone ? SameSiteMode.None : SameSiteMode.Unspecified; + public SameSiteMode SameSite { get; set; } = SameSiteMode.Unspecified; public bool HttpOnly { get; set; } @@ -145,7 +133,7 @@ namespace Microsoft.Net.Http.Headers } // Allow for Unspecified (-1) to skip SameSite - if (SameSite == SameSiteMode.None && !SuppressSameSiteNone) + if (SameSite == SameSiteMode.None) { sameSite = SameSiteNoneToken; length += SeparatorToken.Length + SameSiteToken.Length + EqualsToken.Length + sameSite.Length; @@ -275,7 +263,7 @@ namespace Microsoft.Net.Http.Headers } // Allow for Unspecified (-1) to skip SameSite - if (SameSite == SameSiteMode.None && !SuppressSameSiteNone) + if (SameSite == SameSiteMode.None) { AppendSegment(builder, SameSiteToken, SameSiteNoneToken); } @@ -478,7 +466,7 @@ namespace Microsoft.Net.Http.Headers { if (!ReadEqualsSign(input, ref offset)) { - result.SameSite = SuppressSameSiteNone ? SameSiteMode.Strict : SameSiteMode.Unspecified; + result.SameSite = SameSiteMode.Unspecified; } else { @@ -492,14 +480,13 @@ namespace Microsoft.Net.Http.Headers { result.SameSite = SameSiteMode.Lax; } - else if (!SuppressSameSiteNone - && StringSegment.Equals(enforcementMode, SameSiteNoneToken, StringComparison.OrdinalIgnoreCase)) + else if (StringSegment.Equals(enforcementMode, SameSiteNoneToken, StringComparison.OrdinalIgnoreCase)) { result.SameSite = SameSiteMode.None; } else { - result.SameSite = SuppressSameSiteNone ? SameSiteMode.Strict : SameSiteMode.Unspecified; + result.SameSite = SameSiteMode.Unspecified; } } } diff --git a/src/Http/Headers/test/SetCookieHeaderValueTest.cs b/src/Http/Headers/test/SetCookieHeaderValueTest.cs index 11593b4f93..4f33c54599 100644 --- a/src/Http/Headers/test/SetCookieHeaderValueTest.cs +++ b/src/Http/Headers/test/SetCookieHeaderValueTest.cs @@ -313,28 +313,6 @@ namespace Microsoft.Net.Http.Headers Assert.Equal(expectedValue, input.ToString()); } - [Fact] - public void SetCookieHeaderValue_ToString_SameSiteNoneCompat() - { - SetCookieHeaderValue.SuppressSameSiteNone = true; - - var input = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.None, - }; - - Assert.Equal("name=value", input.ToString()); - - SetCookieHeaderValue.SuppressSameSiteNone = false; - - var input2 = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.None, - }; - - Assert.Equal("name=value; samesite=none", input2.ToString()); - } - [Theory] [MemberData(nameof(SetCookieHeaderDataSet))] public void SetCookieHeaderValue_AppendToStringBuilder(SetCookieHeaderValue input, string expectedValue) @@ -346,32 +324,6 @@ namespace Microsoft.Net.Http.Headers Assert.Equal(expectedValue, builder.ToString()); } - [Fact] - public void SetCookieHeaderValue_AppendToStringBuilder_SameSiteNoneCompat() - { - SetCookieHeaderValue.SuppressSameSiteNone = true; - - var builder = new StringBuilder(); - var input = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.None, - }; - - input.AppendToStringBuilder(builder); - Assert.Equal("name=value", builder.ToString()); - - SetCookieHeaderValue.SuppressSameSiteNone = false; - - var builder2 = new StringBuilder(); - var input2 = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.None, - }; - - input2.AppendToStringBuilder(builder2); - Assert.Equal("name=value; samesite=none", builder2.ToString()); - } - [Theory] [MemberData(nameof(SetCookieHeaderDataSet))] public void SetCookieHeaderValue_Parse_AcceptsValidValues(SetCookieHeaderValue cookie, string expectedValue) @@ -382,31 +334,6 @@ namespace Microsoft.Net.Http.Headers Assert.Equal(expectedValue, header.ToString()); } - [Fact] - public void SetCookieHeaderValue_Parse_AcceptsValidValues_SameSiteNoneCompat() - { - SetCookieHeaderValue.SuppressSameSiteNone = true; - var header = SetCookieHeaderValue.Parse("name=value; samesite=none"); - - var cookie = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.Strict, - }; - - Assert.Equal(cookie, header); - Assert.Equal("name=value; samesite=strict", header.ToString()); - SetCookieHeaderValue.SuppressSameSiteNone = false; - - var header2 = SetCookieHeaderValue.Parse("name=value; samesite=none"); - - var cookie2 = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.None, - }; - Assert.Equal(cookie2, header2); - Assert.Equal("name=value; samesite=none", header2.ToString()); - } - [Theory] [MemberData(nameof(SetCookieHeaderDataSet))] public void SetCookieHeaderValue_TryParse_AcceptsValidValues(SetCookieHeaderValue cookie, string expectedValue) @@ -417,31 +344,6 @@ namespace Microsoft.Net.Http.Headers Assert.Equal(expectedValue, header.ToString()); } - [Fact] - public void SetCookieHeaderValue_TryParse_AcceptsValidValues_SameSiteNoneCompat() - { - SetCookieHeaderValue.SuppressSameSiteNone = true; - Assert.True(SetCookieHeaderValue.TryParse("name=value; samesite=none", out var header)); - var cookie = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.Strict, - }; - - Assert.Equal(cookie, header); - Assert.Equal("name=value; samesite=strict", header.ToString()); - - SetCookieHeaderValue.SuppressSameSiteNone = false; - - Assert.True(SetCookieHeaderValue.TryParse("name=value; samesite=none", out var header2)); - var cookie2 = new SetCookieHeaderValue("name", "value") - { - SameSite = SameSiteMode.None, - }; - - Assert.Equal(cookie2, header2); - Assert.Equal("name=value; samesite=none", header2.ToString()); - } - [Theory] [MemberData(nameof(InvalidSetCookieHeaderDataSet))] public void SetCookieHeaderValue_Parse_RejectsInvalidValues(string value) diff --git a/src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs b/src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs index cf19578fe0..30eefbe417 100644 --- a/src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs +++ b/src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs @@ -6,9 +6,9 @@ namespace Microsoft.AspNetCore.Builder public abstract partial class EndpointBuilder { protected EndpointBuilder() { } - public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.RequestDelegate RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.RequestDelegate RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract Microsoft.AspNetCore.Http.Endpoint Build(); } public partial interface IApplicationBuilder @@ -27,6 +27,7 @@ namespace Microsoft.AspNetCore.Builder public static partial class MapExtensions { public static Microsoft.AspNetCore.Builder.IApplicationBuilder Map(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Http.PathString pathMatch, System.Action configuration) { throw null; } + public static Microsoft.AspNetCore.Builder.IApplicationBuilder Map(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, Microsoft.AspNetCore.Http.PathString pathMatch, bool preserveMatchedPathSegment, System.Action configuration) { throw null; } } public static partial class MapWhenExtensions { @@ -65,8 +66,9 @@ namespace Microsoft.AspNetCore.Builder.Extensions public partial class MapOptions { public MapOptions() { } - public Microsoft.AspNetCore.Http.RequestDelegate Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString PathMatch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.RequestDelegate Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString PathMatch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PreserveMatchedPathSegment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class MapWhenMiddleware { @@ -77,7 +79,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions public partial class MapWhenOptions { public MapWhenOptions() { } - public Microsoft.AspNetCore.Http.RequestDelegate Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.RequestDelegate Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Func Predicate { get { throw null; } set { } } } public partial class UsePathBaseMiddleware @@ -109,15 +111,15 @@ namespace Microsoft.AspNetCore.Http public partial class CookieBuilder { public CookieBuilder() { } - public virtual string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.TimeSpan? Expiration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.TimeSpan? Expiration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual string Name { get { throw null; } set { } } - public virtual string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Http.CookieSecurePolicy SecurePolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Http.CookieSecurePolicy SecurePolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.CookieOptions Build(Microsoft.AspNetCore.Http.HttpContext context) { throw null; } public virtual Microsoft.AspNetCore.Http.CookieOptions Build(Microsoft.AspNetCore.Http.HttpContext context, System.DateTimeOffset expiresFrom) { throw null; } } @@ -130,9 +132,9 @@ namespace Microsoft.AspNetCore.Http public partial class Endpoint { public Endpoint(Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, Microsoft.AspNetCore.Http.EndpointMetadataCollection metadata, string displayName) { } - public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.EndpointMetadataCollection Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.RequestDelegate RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.EndpointMetadataCollection Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.RequestDelegate RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string ToString() { throw null; } } public static partial class EndpointHttpContextExtensions @@ -157,7 +159,7 @@ namespace Microsoft.AspNetCore.Http { private object _dummy; private int _dummyPrimitive; - public object Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Dispose() { } public bool MoveNext() { throw null; } public void Reset() { } @@ -167,6 +169,7 @@ namespace Microsoft.AspNetCore.Http public readonly partial struct FragmentString : System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Http.FragmentString Empty; public FragmentString(string value) { throw null; } public bool HasValue { get { throw null; } } @@ -192,6 +195,7 @@ namespace Microsoft.AspNetCore.Http public readonly partial struct HostString : System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public HostString(string value) { throw null; } public HostString(string host, int port) { throw null; } public bool HasValue { get { throw null; } } @@ -266,7 +270,7 @@ namespace Microsoft.AspNetCore.Http public abstract string Protocol { get; set; } public abstract Microsoft.AspNetCore.Http.IQueryCollection Query { get; set; } public abstract Microsoft.AspNetCore.Http.QueryString QueryString { get; set; } - public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract string Scheme { get; set; } public abstract System.Threading.Tasks.Task ReadFormAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); } @@ -320,6 +324,7 @@ namespace Microsoft.AspNetCore.Http public readonly partial struct PathString : System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Http.PathString Empty; public PathString(string value) { throw null; } public bool HasValue { get { throw null; } } @@ -353,6 +358,7 @@ namespace Microsoft.AspNetCore.Http public readonly partial struct QueryString : System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public static readonly Microsoft.AspNetCore.Http.QueryString Empty; public QueryString(string value) { throw null; } public bool HasValue { get { throw null; } } @@ -510,7 +516,7 @@ namespace Microsoft.AspNetCore.Routing private object _dummy; private int _dummyPrimitive; public Enumerator(Microsoft.AspNetCore.Routing.RouteValueDictionary dictionary) { throw null; } - public System.Collections.Generic.KeyValuePair Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.KeyValuePair Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } object System.Collections.IEnumerator.Current { get { throw null; } } public void Dispose() { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public bool MoveNext() { throw null; } diff --git a/src/Http/Http.Abstractions/src/CookieBuilder.cs b/src/Http/Http.Abstractions/src/CookieBuilder.cs index 46ed33e7f8..429de53cf3 100644 --- a/src/Http/Http.Abstractions/src/CookieBuilder.cs +++ b/src/Http/Http.Abstractions/src/CookieBuilder.cs @@ -11,20 +11,8 @@ namespace Microsoft.AspNetCore.Http /// public class CookieBuilder { - // True (old): https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-3.1 - // False (new): https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.1 - internal static bool SuppressSameSiteNone; - private string _name; - static CookieBuilder() - { - if (AppContext.TryGetSwitch("Microsoft.AspNetCore.SuppressSameSiteNone", out var enabled)) - { - SuppressSameSiteNone = enabled; - } - } - /// /// The name of the cookie. /// @@ -40,7 +28,7 @@ namespace Microsoft.AspNetCore.Http /// The cookie path. /// /// - /// Determines the value that will set on . + /// Determines the value that will set on . /// public virtual string Path { get; set; } @@ -48,7 +36,7 @@ namespace Microsoft.AspNetCore.Http /// The domain to associate the cookie with. /// /// - /// Determines the value that will set on . + /// Determines the value that will set on . /// public virtual string Domain { get; set; } @@ -56,7 +44,7 @@ namespace Microsoft.AspNetCore.Http /// Indicates whether a cookie is accessible by client-side script. /// /// - /// Determines the value that will set on . + /// Determines the value that will set on . /// public virtual bool HttpOnly { get; set; } @@ -64,12 +52,12 @@ namespace Microsoft.AspNetCore.Http /// The SameSite attribute of the cookie. The default value is /// /// - /// Determines the value that will set on . + /// Determines the value that will set on . /// - public virtual SameSiteMode SameSite { get; set; } = SuppressSameSiteNone ? SameSiteMode.None : SameSiteMode.Unspecified; + public virtual SameSiteMode SameSite { get; set; } = SameSiteMode.Unspecified; /// - /// The policy that will be used to determine . + /// The policy that will be used to determine . /// This is determined from the passed to . /// public virtual CookieSecurePolicy SecurePolicy { get; set; } @@ -101,7 +89,7 @@ namespace Microsoft.AspNetCore.Http /// Creates the cookie options from the given with an expiration based on and . /// /// The . - /// The time to use as the base for computing . + /// The time to use as the base for computing . /// The cookie options. public virtual CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom) { diff --git a/src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs b/src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs index 448e2c6f6d..fc33e8fe8a 100644 --- a/src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs +++ b/src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs @@ -21,6 +21,20 @@ namespace Microsoft.AspNetCore.Builder /// The branch to take for positive path matches. /// The instance. public static IApplicationBuilder Map(this IApplicationBuilder app, PathString pathMatch, Action configuration) + { + return Map(app, pathMatch, preserveMatchedPathSegment: false, configuration); + } + + /// + /// Branches the request pipeline based on matches of the given request path. If the request path starts with + /// the given path, the branch is executed. + /// + /// The instance. + /// The request path to match. + /// if false, matched path would be removed from Request.Path and added to Request.PathBase. + /// The branch to take for positive path matches. + /// The instance. + public static IApplicationBuilder Map(this IApplicationBuilder app, PathString pathMatch, bool preserveMatchedPathSegment, Action configuration) { if (app == null) { @@ -46,8 +60,9 @@ namespace Microsoft.AspNetCore.Builder { Branch = branch, PathMatch = pathMatch, + PreserveMatchedPathSegment = preserveMatchedPathSegment }; return app.Use(next => new MapMiddleware(next, options).Invoke); } } -} \ No newline at end of file +} diff --git a/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs b/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs index 4215b82697..0ba76507c8 100644 --- a/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs +++ b/src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs @@ -48,16 +48,17 @@ namespace Microsoft.AspNetCore.Builder.Extensions throw new ArgumentNullException(nameof(context)); } - PathString matchedPath; - PathString remainingPath; - - if (context.Request.Path.StartsWithSegments(_options.PathMatch, out matchedPath, out remainingPath)) + if (context.Request.Path.StartsWithSegments(_options.PathMatch, out var matchedPath, out var remainingPath)) { - // Update the path var path = context.Request.Path; var pathBase = context.Request.PathBase; - context.Request.PathBase = pathBase.Add(matchedPath); - context.Request.Path = remainingPath; + + if (!_options.PreserveMatchedPathSegment) + { + // Update the path + context.Request.PathBase = pathBase.Add(matchedPath); + context.Request.Path = remainingPath; + } try { @@ -65,8 +66,11 @@ namespace Microsoft.AspNetCore.Builder.Extensions } finally { - context.Request.PathBase = pathBase; - context.Request.Path = path; + if (!_options.PreserveMatchedPathSegment) + { + context.Request.PathBase = pathBase; + context.Request.Path = path; + } } } else @@ -75,4 +79,4 @@ namespace Microsoft.AspNetCore.Builder.Extensions } } } -} \ No newline at end of file +} diff --git a/src/Http/Http.Abstractions/src/Extensions/MapOptions.cs b/src/Http/Http.Abstractions/src/Extensions/MapOptions.cs index 60adc74379..d914aa4210 100644 --- a/src/Http/Http.Abstractions/src/Extensions/MapOptions.cs +++ b/src/Http/Http.Abstractions/src/Extensions/MapOptions.cs @@ -19,5 +19,11 @@ namespace Microsoft.AspNetCore.Builder.Extensions /// The branch taken for a positive match. /// public RequestDelegate Branch { get; set; } + + /// + /// If false, matched path would be removed from Request.Path and added to Request.PathBase + /// Defaults to false. + /// + public bool PreserveMatchedPathSegment { get; set; } } -} \ No newline at end of file +} diff --git a/src/Http/Http.Abstractions/src/HostString.cs b/src/Http/Http.Abstractions/src/HostString.cs index 23850231bf..0f7cbd73f6 100644 --- a/src/Http/Http.Abstractions/src/HostString.cs +++ b/src/Http/Http.Abstractions/src/HostString.cs @@ -223,7 +223,7 @@ namespace Microsoft.AspNetCore.Http /// "abc.example.com:443" but not "example.com:443". /// Matching is case insensitive. /// - /// true if matches any of the patterns. + /// if matches any of the patterns. public static bool MatchesAny(StringSegment value, IList patterns) { if (value == null) @@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.Http /// Compares the equality of the Value property, ignoring case. /// /// The to compare against. - /// true if they have the same value. + /// if they have the same value. public bool Equals(HostString other) { if (!HasValue && !other.HasValue) @@ -296,7 +296,7 @@ namespace Microsoft.AspNetCore.Http /// Compares against the given object only if it is a HostString. /// /// The to compare against. - /// true if they have the same value. + /// if they have the same value. public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) @@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.Http /// /// The left parameter. /// The right parameter. - /// true if both 's have the same value. + /// if both 's have the same value. public static bool operator ==(HostString left, HostString right) { return left.Equals(right); @@ -331,7 +331,7 @@ namespace Microsoft.AspNetCore.Http /// /// The left parameter. /// The right parameter. - /// true if both 's values are not equal. + /// if both 's values are not equal. public static bool operator !=(HostString left, HostString right) { return !left.Equals(right); diff --git a/src/Http/Http.Abstractions/src/HttpMethods.cs b/src/Http/Http.Abstractions/src/HttpMethods.cs index 05a5f2e834..350b98faf2 100644 --- a/src/Http/Http.Abstractions/src/HttpMethods.cs +++ b/src/Http/Http.Abstractions/src/HttpMethods.cs @@ -5,12 +5,15 @@ using System; namespace Microsoft.AspNetCore.Http { + /// + /// Contains methods to verify the request method of an HTTP request. + /// public static class HttpMethods { // We are intentionally using 'static readonly' here instead of 'const'. - // 'const' values would be embedded in to each assembly that used them + // 'const' values would be embedded into each assembly that used them // and each consuming assembly would have a different 'string' instance. - // Using .'static readonly' means that all consumers get thee exact same + // Using .'static readonly' means that all consumers get these exact same // 'string' instance, which means the 'ReferenceEquals' checks below work // and allow us to optimize comparisons when these constants are used. @@ -25,46 +28,109 @@ namespace Microsoft.AspNetCore.Http public static readonly string Put = "PUT"; public static readonly string Trace = "TRACE"; + /// + /// Returns a value that indicates if the HTTP request method is CONNECT. + /// + /// The HTTP request method. + /// + /// if the method is CONNECT; otherwise, . + /// public static bool IsConnect(string method) { return object.ReferenceEquals(Connect, method) || StringComparer.OrdinalIgnoreCase.Equals(Connect, method); } + /// + /// Returns a value that indicates if the HTTP request method is DELETE. + /// + /// The HTTP request method. + /// + /// if the method is DELETE; otherwise, . + /// public static bool IsDelete(string method) { return object.ReferenceEquals(Delete, method) || StringComparer.OrdinalIgnoreCase.Equals(Delete, method); } + /// + /// Returns a value that indicates if the HTTP request method is GET. + /// + /// The HTTP request method. + /// + /// if the method is GET; otherwise, . + /// public static bool IsGet(string method) { return object.ReferenceEquals(Get, method) || StringComparer.OrdinalIgnoreCase.Equals(Get, method); } + /// + /// Returns a value that indicates if the HTTP request method is HEAD. + /// + /// The HTTP request method. + /// + /// if the method is HEAD; otherwise, . + /// public static bool IsHead(string method) { return object.ReferenceEquals(Head, method) || StringComparer.OrdinalIgnoreCase.Equals(Head, method); } + /// + /// Returns a value that indicates if the HTTP request method is OPTIONS. + /// + /// The HTTP request method. + /// + /// if the method is OPTIONS; otherwise, . + /// public static bool IsOptions(string method) { return object.ReferenceEquals(Options, method) || StringComparer.OrdinalIgnoreCase.Equals(Options, method); } + /// + /// Returns a value that indicates if the HTTP request method is PATCH. + /// + /// The HTTP request method. + /// + /// if the method is PATCH; otherwise, . + /// public static bool IsPatch(string method) { return object.ReferenceEquals(Patch, method) || StringComparer.OrdinalIgnoreCase.Equals(Patch, method); } + /// + /// Returns a value that indicates if the HTTP request method is POST. + /// + /// The HTTP request method. + /// + /// if the method is POST; otherwise, . + /// public static bool IsPost(string method) { return object.ReferenceEquals(Post, method) || StringComparer.OrdinalIgnoreCase.Equals(Post, method); } + /// + /// Returns a value that indicates if the HTTP request method is PUT. + /// + /// The HTTP request method. + /// + /// if the method is PUT; otherwise, . + /// public static bool IsPut(string method) { return object.ReferenceEquals(Put, method) || StringComparer.OrdinalIgnoreCase.Equals(Put, method); } + /// + /// Returns a value that indicates if the HTTP request method is TRACE. + /// + /// The HTTP request method. + /// + /// if the method is TRACE; otherwise, . + /// public static bool IsTrace(string method) { return object.ReferenceEquals(Trace, method) || StringComparer.OrdinalIgnoreCase.Equals(Trace, method); diff --git a/src/Http/Http.Abstractions/src/HttpRequest.cs b/src/Http/Http.Abstractions/src/HttpRequest.cs index 1b13dc10cc..373b82588a 100644 --- a/src/Http/Http.Abstractions/src/HttpRequest.cs +++ b/src/Http/Http.Abstractions/src/HttpRequest.cs @@ -45,9 +45,9 @@ namespace Microsoft.AspNetCore.Http public abstract HostString Host { get; set; } /// - /// Gets or sets the RequestPathBase. + /// Gets or sets the base path for the request. The path base should not end with a trailing slash. /// - /// The RequestPathBase. + /// The base path for the request. public abstract PathString PathBase { get; set; } /// diff --git a/src/Http/Http.Abstractions/src/IHttpContextAccessor.cs b/src/Http/Http.Abstractions/src/IHttpContextAccessor.cs index dc8ec34a7c..b02c78d144 100644 --- a/src/Http/Http.Abstractions/src/IHttpContextAccessor.cs +++ b/src/Http/Http.Abstractions/src/IHttpContextAccessor.cs @@ -3,8 +3,18 @@ namespace Microsoft.AspNetCore.Http { + /// + /// Provides access to the current , if one is available. + /// + /// + /// This interface should be used with caution. It relies on which can have a negative performance impact on async calls. + /// It also creates a dependency on "ambient state" which can make testing more difficult. + /// public interface IHttpContextAccessor { + /// + /// Gets or sets the current . Returns if there is no active . + /// HttpContext HttpContext { get; set; } } -} \ No newline at end of file +} diff --git a/src/Http/Http.Abstractions/src/IHttpContextFactory.cs b/src/Http/Http.Abstractions/src/IHttpContextFactory.cs index 7d049626c3..4a73724219 100644 --- a/src/Http/Http.Abstractions/src/IHttpContextFactory.cs +++ b/src/Http/Http.Abstractions/src/IHttpContextFactory.cs @@ -5,9 +5,22 @@ using Microsoft.AspNetCore.Http.Features; namespace Microsoft.AspNetCore.Http { + /// + /// Provides methods to create and dispose of instances. + /// public interface IHttpContextFactory { + /// + /// Creates an instance for the specified set of HTTP features. + /// + /// The collection of HTTP features to set on the created instance. + /// The instance. HttpContext Create(IFeatureCollection featureCollection); + + /// + /// Releases resources held by the . + /// + /// The to dispose. void Dispose(HttpContext httpContext); } } diff --git a/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs b/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs index a30e99603c..f9d935b086 100644 --- a/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs +++ b/src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs @@ -54,13 +54,13 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/foo", "/Bar", "/foo/cho/")] [InlineData("/foo/cho", "/Bar", "/foo/cho")] [InlineData("/foo/cho", "/Bar", "/foo/cho/do")] - public void PathMatchFunc_BranchTaken(string matchPath, string basePath, string requestPath) + public async Task PathMatchFunc_BranchTaken(string matchPath, string basePath, string requestPath) { HttpContext context = CreateRequest(basePath, requestPath); var builder = new ApplicationBuilder(serviceProvider: null); builder.Map(matchPath, UseSuccess); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(basePath, context.Request.PathBase.Value); @@ -82,19 +82,47 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/foo", "/Bar", "/Foo/Cho/")] [InlineData("/foo/cho", "/Bar", "/Foo/Cho")] [InlineData("/foo/cho", "/Bar", "/Foo/Cho/do")] - public void PathMatchAction_BranchTaken(string matchPath, string basePath, string requestPath) + public async Task PathMatchAction_BranchTaken(string matchPath, string basePath, string requestPath) { HttpContext context = CreateRequest(basePath, requestPath); var builder = new ApplicationBuilder(serviceProvider: null); builder.Map(matchPath, subBuilder => subBuilder.Run(Success)); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(basePath + requestPath.Substring(0, matchPath.Length), (string)context.Items["test.PathBase"]); Assert.Equal(requestPath.Substring(matchPath.Length), context.Items["test.Path"]); } + [Theory] + [InlineData("/foo", "", "/foo")] + [InlineData("/foo", "", "/foo/")] + [InlineData("/foo", "/Bar", "/foo")] + [InlineData("/foo", "/Bar", "/foo/cho")] + [InlineData("/foo", "/Bar", "/foo/cho/")] + [InlineData("/foo/cho", "/Bar", "/foo/cho")] + [InlineData("/foo/cho", "/Bar", "/foo/cho/do")] + [InlineData("/foo", "", "/Foo")] + [InlineData("/foo", "", "/Foo/")] + [InlineData("/foo", "/Bar", "/Foo")] + [InlineData("/foo", "/Bar", "/Foo/Cho")] + [InlineData("/foo", "/Bar", "/Foo/Cho/")] + [InlineData("/foo/cho", "/Bar", "/Foo/Cho")] + [InlineData("/foo/cho", "/Bar", "/Foo/Cho/do")] + public async Task PathMatchAction_BranchTaken_WithPreserveMatchedPathSegment(string matchPath, string basePath, string requestPath) + { + HttpContext context = CreateRequest(basePath, requestPath); + var builder = new ApplicationBuilder(serviceProvider: null); + builder.Map(matchPath, true, subBuilder => subBuilder.Run(Success)); + var app = builder.Build(); + await app.Invoke(context); + + Assert.Equal(200, context.Response.StatusCode); + Assert.Equal(basePath, (string)context.Items["test.PathBase"]); + Assert.Equal(requestPath, context.Items["test.Path"]); + } + [Theory] [InlineData("/")] [InlineData("/foo/")] @@ -112,14 +140,14 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/foo", "/foo", "/bar")] [InlineData("/foo", "", "/bar/foo")] [InlineData("/foo/bar", "/foo", "/bar")] - public void PathMismatchFunc_PassedThrough(string matchPath, string basePath, string requestPath) + public async Task PathMismatchFunc_PassedThrough(string matchPath, string basePath, string requestPath) { HttpContext context = CreateRequest(basePath, requestPath); var builder = new ApplicationBuilder(serviceProvider: null); builder.Map(matchPath, UseNotImplemented); builder.Run(Success); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(basePath, context.Request.PathBase.Value); @@ -134,14 +162,14 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/foo", "/foo", "/bar")] [InlineData("/foo", "", "/bar/foo")] [InlineData("/foo/bar", "/foo", "/bar")] - public void PathMismatchAction_PassedThrough(string matchPath, string basePath, string requestPath) + public async Task PathMismatchAction_PassedThrough(string matchPath, string basePath, string requestPath) { HttpContext context = CreateRequest(basePath, requestPath); var builder = new ApplicationBuilder(serviceProvider: null); builder.Map(matchPath, UseNotImplemented); builder.Run(Success); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(basePath, context.Request.PathBase.Value); @@ -149,7 +177,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions } [Fact] - public void ChainedRoutes_Success() + public async Task ChainedRoutes_Success() { var builder = new ApplicationBuilder(serviceProvider: null); builder.Map("/route1", map => @@ -161,28 +189,28 @@ namespace Microsoft.AspNetCore.Builder.Extensions var app = builder.Build(); HttpContext context = CreateRequest(string.Empty, "/route1"); - Assert.Throws(() => app.Invoke(context).Wait()); + await Assert.ThrowsAsync(() => app.Invoke(context)); context = CreateRequest(string.Empty, "/route1/subroute1"); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(string.Empty, context.Request.PathBase.Value); Assert.Equal("/route1/subroute1", context.Request.Path.Value); context = CreateRequest(string.Empty, "/route2"); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(404, context.Response.StatusCode); Assert.Equal(string.Empty, context.Request.PathBase.Value); Assert.Equal("/route2", context.Request.Path.Value); context = CreateRequest(string.Empty, "/route2/subroute2"); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(string.Empty, context.Request.PathBase.Value); Assert.Equal("/route2/subroute2", context.Request.Path.Value); context = CreateRequest(string.Empty, "/route2/subroute2/subsub2"); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); Assert.Equal(string.Empty, context.Request.PathBase.Value); Assert.Equal("/route2/subroute2/subsub2", context.Request.Path.Value); diff --git a/src/Http/Http.Abstractions/test/MapPredicateMiddlewareTests.cs b/src/Http/Http.Abstractions/test/MapPredicateMiddlewareTests.cs index 9274ab4207..048d522579 100644 --- a/src/Http/Http.Abstractions/test/MapPredicateMiddlewareTests.cs +++ b/src/Http/Http.Abstractions/test/MapPredicateMiddlewareTests.cs @@ -61,44 +61,44 @@ namespace Microsoft.AspNetCore.Builder.Extensions } [Fact] - public void PredicateTrue_BranchTaken() + public async Task PredicateTrue_BranchTaken() { HttpContext context = CreateRequest(); var builder = new ApplicationBuilder(serviceProvider: null); builder.MapWhen(TruePredicate, UseSuccess); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); } [Fact] - public void PredicateTrueAction_BranchTaken() + public async Task PredicateTrueAction_BranchTaken() { HttpContext context = CreateRequest(); var builder = new ApplicationBuilder(serviceProvider: null); builder.MapWhen(TruePredicate, UseSuccess); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); } [Fact] - public void PredicateFalseAction_PassThrough() + public async Task PredicateFalseAction_PassThrough() { HttpContext context = CreateRequest(); var builder = new ApplicationBuilder(serviceProvider: null); builder.MapWhen(FalsePredicate, UseNotImplemented); builder.Run(Success); var app = builder.Build(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); } [Fact] - public void ChainedPredicates_Success() + public async Task ChainedPredicates_Success() { var builder = new ApplicationBuilder(serviceProvider: null); builder.MapWhen(TruePredicate, map1 => @@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions var app = builder.Build(); HttpContext context = CreateRequest(); - app.Invoke(context).Wait(); + await app.Invoke(context); Assert.Equal(200, context.Response.StatusCode); } diff --git a/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs b/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs index 4b8e9d71cb..e5f7903bc5 100644 --- a/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs +++ b/src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -76,9 +76,9 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/base/more", "/oldbase", "/base/more", "/oldbase/base/more", "")] [InlineData("/base/more", "/oldbase", "/base/more/something", "/oldbase/base/more", "/something")] [InlineData("/base/more", "/oldbase", "/base/more/something/", "/oldbase/base/more", "/something/")] - public void RequestPathBaseContainingPathBase_IsSplit(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + public Task RequestPathBaseContainingPathBase_IsSplit(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { - TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); + return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); } [Theory] @@ -90,9 +90,9 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/base", "/oldbase", "/baseandsomething", "/oldbase", "/baseandsomething")] [InlineData("/base", "/oldbase", "/ba", "/oldbase", "/ba")] [InlineData("/base", "/oldbase", "/ba/se", "/oldbase", "/ba/se")] - public void RequestPathBaseNotContainingPathBase_IsNotSplit(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + public Task RequestPathBaseNotContainingPathBase_IsNotSplit(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { - TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); + return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); } [Theory] @@ -106,17 +106,17 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/base", "/oldbase", "/base/", "/oldbase/base", "/")] [InlineData("/base/", "/oldbase", "/base", "/oldbase/base", "")] [InlineData("/base/", "/oldbase", "/base/", "/oldbase/base", "/")] - public void PathBaseNeverEndsWithSlash(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + public Task PathBaseNeverEndsWithSlash(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { - TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); + return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); } [Theory] [InlineData("/base", "", "/Base/Something", "/Base", "/Something")] [InlineData("/base", "/OldBase", "/Base/Something", "/OldBase/Base", "/Something")] - public void PathBaseAndPathPreserveRequestCasing(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + public Task PathBaseAndPathPreserveRequestCasing(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { - TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); + return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); } [Theory] @@ -126,12 +126,12 @@ namespace Microsoft.AspNetCore.Builder.Extensions [InlineData("/b♫se", "/oldb♫se", "/b♫se/something", "/oldb♫se/b♫se", "/something")] [InlineData("/b♫se", "/oldb♫se", "/b♫se/Something", "/oldb♫se/b♫se", "/Something")] [InlineData("/b♫se", "/oldb♫se", "/B♫se/something", "/oldb♫se/B♫se", "/something")] - public void PathBaseCanHaveUnicodeCharacters(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + public Task PathBaseCanHaveUnicodeCharacters(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { - TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); + return TestPathBase(registeredPathBase, pathBase, requestPath, expectedPathBase, expectedPath); } - private static void TestPathBase(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) + private static async Task TestPathBase(string registeredPathBase, string pathBase, string requestPath, string expectedPathBase, string expectedPath) { HttpContext requestContext = CreateRequest(pathBase, requestPath); var builder = CreateBuilder() @@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions context.Items["test.PathBase"] = context.Request.PathBase; return Task.FromResult(0); }); - builder.Build().Invoke(requestContext).Wait(); + await builder.Build().Invoke(requestContext); // Assert path and pathBase are split after middleware Assert.Equal(expectedPath, ((PathString)requestContext.Items["test.Path"]).Value); diff --git a/src/Http/Http.Abstractions/test/UseWhenExtensionsTests.cs b/src/Http/Http.Abstractions/test/UseWhenExtensionsTests.cs index 902a003b26..901454b62e 100644 --- a/src/Http/Http.Abstractions/test/UseWhenExtensionsTests.cs +++ b/src/Http/Http.Abstractions/test/UseWhenExtensionsTests.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions } [Fact] - public void PredicateTrue_BranchTaken_WillRejoin() + public async Task PredicateTrue_BranchTaken_WillRejoin() { // Arrange var context = CreateContext(); @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions parent.Use(Increment("parent")); // Act - parent.Build().Invoke(context).Wait(); + await parent.Build().Invoke(context); // Assert Assert.Equal(1, Count(context, "parent")); @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions } [Fact] - public void PredicateTrue_BranchTaken_CanTerminate() + public async Task PredicateTrue_BranchTaken_CanTerminate() { // Arrange var context = CreateContext(); @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions parent.Use(Increment("parent")); // Act - parent.Build().Invoke(context).Wait(); + await parent.Build().Invoke(context); // Assert Assert.Equal(0, Count(context, "parent")); @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions } [Fact] - public void PredicateFalse_PassThrough() + public async Task PredicateFalse_PassThrough() { // Arrange var context = CreateContext(); @@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions parent.Use(Increment("parent")); // Act - parent.Build().Invoke(context).Wait(); + await parent.Build().Invoke(context); // Assert Assert.Equal(1, Count(context, "parent")); diff --git a/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp.cs b/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp.cs index 4023268f5b..14f3400e95 100644 --- a/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp.cs +++ b/src/Http/Http.Extensions/ref/Microsoft.AspNetCore.Http.Extensions.netcoreapp.cs @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Http.Headers public System.Collections.Generic.IList Cookie { get { throw null; } set { } } public System.DateTimeOffset? Date { get { throw null; } set { } } public System.DateTimeOffset? Expires { get { throw null; } set { } } - public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Http.HostString Host { get { throw null; } set { } } public System.Collections.Generic.IList IfMatch { get { throw null; } set { } } public System.DateTimeOffset? IfModifiedSince { get { throw null; } set { } } @@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Http.Headers public System.DateTimeOffset? Date { get { throw null; } set { } } public Microsoft.Net.Http.Headers.EntityTagHeaderValue ETag { get { throw null; } set { } } public System.DateTimeOffset? Expires { get { throw null; } set { } } - public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.DateTimeOffset? LastModified { get { throw null; } set { } } public System.Uri Location { get { throw null; } set { } } public System.Collections.Generic.IList SetCookie { get { throw null; } set { } } diff --git a/src/Http/Http.Extensions/src/RequestHeaders.cs b/src/Http/Http.Extensions/src/RequestHeaders.cs index 12246922d4..2874be00b8 100644 --- a/src/Http/Http.Extensions/src/RequestHeaders.cs +++ b/src/Http/Http.Extensions/src/RequestHeaders.cs @@ -279,11 +279,27 @@ namespace Microsoft.AspNetCore.Http.Headers } } + /// + /// Gets the value of header with . + /// + /// must contain a TryParse method with the signature public static bool TryParse(string, out T). + /// The type of the header. + /// The given type must have a static TryParse method. + /// The name of the header to retrieve. + /// The value of the header. public T Get(string name) { return Headers.Get(name); } + /// + /// Gets the values of header with . + /// + /// must contain a TryParseList method with the signature public static bool TryParseList(IList<string>, out IList<T>). + /// The type of the header. + /// The given type must have a static TryParseList method. + /// The name of the header to retrieve. + /// List of values of the header. public IList GetList(string name) { return Headers.GetList(name); diff --git a/src/Http/Http.Extensions/src/ResponseHeaders.cs b/src/Http/Http.Extensions/src/ResponseHeaders.cs index 87e3c0318c..55aec1f575 100644 --- a/src/Http/Http.Extensions/src/ResponseHeaders.cs +++ b/src/Http/Http.Extensions/src/ResponseHeaders.cs @@ -158,11 +158,27 @@ namespace Microsoft.AspNetCore.Http.Headers } } + /// + /// Gets the value of header with . + /// + /// must contain a TryParse method with the signature public static bool TryParse(string, out T). + /// The type of the header. + /// The given type must have a static TryParse method. + /// The name of the header to retrieve. + /// The value of the header. public T Get(string name) { return Headers.Get(name); } + /// + /// Gets the values of header with . + /// + /// must contain a TryParseList method with the signature public static bool TryParseList(IList<string>, out IList<T>). + /// The type of the header. + /// The given type must have a static TryParseList method. + /// The name of the header to retrieve. + /// List of values of the header. public IList GetList(string name) { return Headers.GetList(name); @@ -208,4 +224,4 @@ namespace Microsoft.AspNetCore.Http.Headers Headers.AppendList(name, values); } } -} \ No newline at end of file +} diff --git a/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netcoreapp.cs b/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netcoreapp.cs index 0ba8551260..45f7f9d135 100644 --- a/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netcoreapp.cs +++ b/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netcoreapp.cs @@ -6,14 +6,14 @@ namespace Microsoft.AspNetCore.Http public partial class CookieOptions { public CookieOptions() { } - public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IFormCollection : System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable { @@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Http public partial class WebSocketAcceptContext { public WebSocketAcceptContext() { } - public virtual string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Http.Features @@ -116,8 +116,8 @@ namespace Microsoft.AspNetCore.Http.Features private int _dummyPrimitive; public TCache Cache; public FeatureReferences(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection) { throw null; } - public Microsoft.AspNetCore.Http.Features.IFeatureCollection Collection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Revision { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.Features.IFeatureCollection Collection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Revision { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public TFeature Fetch(ref TFeature cached, System.Func factory) where TFeature : class { throw null; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public TFeature Fetch(ref TFeature cached, TState state, System.Func factory) where TFeature : class { throw null; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public void Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection) { } diff --git a/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs b/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs index 0ba8551260..45f7f9d135 100644 --- a/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs +++ b/src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs @@ -6,14 +6,14 @@ namespace Microsoft.AspNetCore.Http public partial class CookieOptions { public CookieOptions() { } - public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IFormCollection : System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable { @@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Http public partial class WebSocketAcceptContext { public WebSocketAcceptContext() { } - public virtual string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Http.Features @@ -116,8 +116,8 @@ namespace Microsoft.AspNetCore.Http.Features private int _dummyPrimitive; public TCache Cache; public FeatureReferences(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection) { throw null; } - public Microsoft.AspNetCore.Http.Features.IFeatureCollection Collection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Revision { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.Features.IFeatureCollection Collection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Revision { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public TFeature Fetch(ref TFeature cached, System.Func factory) where TFeature : class { throw null; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public TFeature Fetch(ref TFeature cached, TState state, System.Func factory) where TFeature : class { throw null; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public void Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection) { } diff --git a/src/Http/Http.Features/src/CookieOptions.cs b/src/Http/Http.Features/src/CookieOptions.cs index 6720ad6f05..833eeedea2 100644 --- a/src/Http/Http.Features/src/CookieOptions.cs +++ b/src/Http/Http.Features/src/CookieOptions.cs @@ -10,18 +10,6 @@ namespace Microsoft.AspNetCore.Http /// public class CookieOptions { - // True (old): https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-3.1 - // False (new): https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.1 - internal static bool SuppressSameSiteNone; - - static CookieOptions() - { - if (AppContext.TryGetSwitch("Microsoft.AspNetCore.SuppressSameSiteNone", out var enabled)) - { - SuppressSameSiteNone = enabled; - } - } - /// /// Creates a default cookie with a path of '/'. /// @@ -58,7 +46,7 @@ namespace Microsoft.AspNetCore.Http /// Gets or sets the value for the SameSite attribute of the cookie. The default value is /// /// The representing the enforcement mode of the cookie. - public SameSiteMode SameSite { get; set; } = SuppressSameSiteNone ? SameSiteMode.None : SameSiteMode.Unspecified; + public SameSiteMode SameSite { get; set; } = SameSiteMode.Unspecified; /// /// Gets or sets a value that indicates whether a cookie is accessible by client-side script. diff --git a/src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp.cs b/src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp.cs index 56489b8752..ed6962230f 100644 --- a/src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp.cs +++ b/src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Builder public ApplicationBuilder(System.IServiceProvider serviceProvider) { } public ApplicationBuilder(System.IServiceProvider serviceProvider, object server) { } public System.IServiceProvider ApplicationServices { get { throw null; } set { } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Http.Features.IFeatureCollection ServerFeatures { get { throw null; } } public Microsoft.AspNetCore.Http.RequestDelegate Build() { throw null; } public Microsoft.AspNetCore.Builder.IApplicationBuilder New() { throw null; } @@ -20,11 +20,11 @@ namespace Microsoft.AspNetCore.Http public partial class BindingAddress { public BindingAddress() { } - public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool IsUnixPipe { get { throw null; } } - public string PathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Port { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string PathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Port { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string UnixPipePath { get { throw null; } } public override bool Equals(object obj) { throw null; } public override int GetHashCode() { throw null; } @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Http public DefaultHttpContext(Microsoft.AspNetCore.Http.Features.IFeatureCollection features) { } public override Microsoft.AspNetCore.Http.ConnectionInfo Connection { get { throw null; } } public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get { throw null; } } - public Microsoft.AspNetCore.Http.Features.FormOptions FormOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.Features.FormOptions FormOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } } public override System.Collections.Generic.IDictionary Items { get { throw null; } set { } } @@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Http public override System.Threading.CancellationToken RequestAborted { get { throw null; } set { } } public override System.IServiceProvider RequestServices { get { throw null; } set { } } public override Microsoft.AspNetCore.Http.HttpResponse Response { get { throw null; } } - public Microsoft.Extensions.DependencyInjection.IServiceScopeFactory ServiceScopeFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.DependencyInjection.IServiceScopeFactory ServiceScopeFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.Http.ISession Session { get { throw null; } set { } } public override string TraceIdentifier { get { throw null; } set { } } public override System.Security.Claims.ClaimsPrincipal User { get { throw null; } set { } } @@ -84,10 +84,10 @@ namespace Microsoft.AspNetCore.Http public FormFile(System.IO.Stream baseStream, long baseStreamOffset, long length, string name, string fileName) { } public string ContentDisposition { get { throw null; } set { } } public string ContentType { get { throw null; } set { } } - public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Length { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Length { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void CopyTo(System.IO.Stream target) { } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream target, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -107,7 +107,7 @@ namespace Microsoft.AspNetCore.Http public HeaderDictionary(int capacity) { } public long? ContentLength { get { throw null; } set { } } public int Count { get { throw null; } } - public bool IsReadOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool IsReadOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.Extensions.Primitives.StringValues this[string key] { get { throw null; } set { } } public System.Collections.Generic.ICollection Keys { get { throw null; } } Microsoft.Extensions.Primitives.StringValues System.Collections.Generic.IDictionary.this[string key] { get { throw null; } set { } } @@ -204,8 +204,8 @@ namespace Microsoft.AspNetCore.Http { public StreamResponseBodyFeature(System.IO.Stream stream) { } public StreamResponseBodyFeature(System.IO.Stream stream, Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature priorFeature) { } - public Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature PriorFeature { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.IO.Stream Stream { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature PriorFeature { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.IO.Stream Stream { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.IO.Pipelines.PipeWriter Writer { get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task CompleteAsync() { throw null; } @@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Http.Features public partial class DefaultSessionFeature : Microsoft.AspNetCore.Http.Features.ISessionFeature { public DefaultSessionFeature() { } - public Microsoft.AspNetCore.Http.ISession Session { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.ISession Session { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class FormFeature : Microsoft.AspNetCore.Http.Features.IFormFeature { @@ -241,38 +241,38 @@ namespace Microsoft.AspNetCore.Http.Features public const long DefaultMultipartBodyLengthLimit = (long)134217728; public const int DefaultMultipartBoundaryLengthLimit = 128; public FormOptions() { } - public bool BufferBody { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long BufferBodyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int KeyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MemoryBufferThreshold { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long MultipartBodyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MultipartBoundaryLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MultipartHeadersCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MultipartHeadersLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ValueCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ValueLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool BufferBody { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long BufferBodyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int KeyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MemoryBufferThreshold { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long MultipartBodyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MultipartBoundaryLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MultipartHeadersCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MultipartHeadersLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ValueCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ValueLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HttpConnectionFeature : Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature { public HttpConnectionFeature() { } - public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.IPAddress LocalIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int LocalPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.IPAddress RemoteIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RemotePort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.IPAddress LocalIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int LocalPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.IPAddress RemoteIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RemotePort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HttpRequestFeature : Microsoft.AspNetCore.Http.Features.IHttpRequestFeature { public HttpRequestFeature() { } - public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Method { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string QueryString { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RawTarget { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Method { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string QueryString { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RawTarget { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HttpRequestIdentifierFeature : Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature { @@ -282,24 +282,24 @@ namespace Microsoft.AspNetCore.Http.Features public partial class HttpRequestLifetimeFeature : Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature { public HttpRequestLifetimeFeature() { } - public System.Threading.CancellationToken RequestAborted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Threading.CancellationToken RequestAborted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Abort() { } } public partial class HttpResponseFeature : Microsoft.AspNetCore.Http.Features.IHttpResponseFeature { public HttpResponseFeature() { } - public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual bool HasStarted { get { throw null; } } - public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReasonPhrase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReasonPhrase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void OnCompleted(System.Func callback, object state) { } public virtual void OnStarting(System.Func callback, object state) { } } public partial class ItemsFeature : Microsoft.AspNetCore.Http.Features.IItemsFeature { public ItemsFeature() { } - public System.Collections.Generic.IDictionary Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class QueryFeature : Microsoft.AspNetCore.Http.Features.IQueryFeature { @@ -339,12 +339,12 @@ namespace Microsoft.AspNetCore.Http.Features public partial class ServiceProvidersFeature : Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature { public ServiceProvidersFeature() { } - public System.IServiceProvider RequestServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IServiceProvider RequestServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TlsConnectionFeature : Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature { public TlsConnectionFeature() { } - public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Threading.Tasks.Task GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken) { throw null; } } } @@ -353,7 +353,7 @@ namespace Microsoft.AspNetCore.Http.Features.Authentication public partial class HttpAuthenticationFeature : Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature { public HttpAuthenticationFeature() { } - public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Http/Http/src/BindingAddress.cs b/src/Http/Http/src/BindingAddress.cs index 67a62e0c42..38e552b381 100644 --- a/src/Http/Http/src/BindingAddress.cs +++ b/src/Http/Http/src/BindingAddress.cs @@ -3,6 +3,8 @@ using System; using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Http { @@ -32,10 +34,17 @@ namespace Microsoft.AspNetCore.Http throw new InvalidOperationException("Binding address is not a unix pipe."); } - return Host.Substring(UnixPipeHostPrefix.Length - 1); + var unixPipeHostPrefixLength = UnixPipeHostPrefix.Length; + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // "/" character in unix refers to root. Windows has drive letters and volume separator (c:) + unixPipeHostPrefixLength--; + } + return Host.Substring(unixPipeHostPrefixLength); } } + public override string ToString() { if (IsUnixPipe) @@ -88,7 +97,18 @@ namespace Microsoft.AspNetCore.Http } else { - pathDelimiterStart = address.IndexOf(":", schemeDelimiterEnd + UnixPipeHostPrefix.Length, StringComparison.Ordinal); + var unixPipeHostPrefixLength = UnixPipeHostPrefix.Length; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Windows has drive letters and volume separator (c:) + unixPipeHostPrefixLength += 2; + if (schemeDelimiterEnd + unixPipeHostPrefixLength > address.Length) + { + throw new FormatException($"Invalid url: '{address}'"); + } + } + + pathDelimiterStart = address.IndexOf(":", schemeDelimiterEnd + unixPipeHostPrefixLength, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart + ":".Length; } @@ -141,6 +161,11 @@ namespace Microsoft.AspNetCore.Http throw new FormatException($"Invalid url: '{address}'"); } + if (isUnixPipe && !Path.IsPathRooted(serverAddress.UnixPipePath)) + { + throw new FormatException($"Invalid url, unix socket path must be absolute: '{address}'"); + } + if (address[address.Length - 1] == '/') { serverAddress.PathBase = address.Substring(pathDelimiterEnd, address.Length - pathDelimiterEnd - 1); diff --git a/src/Http/Http/src/DefaultHttpContext.cs b/src/Http/Http/src/DefaultHttpContext.cs index 102e96947d..59c7739e86 100644 --- a/src/Http/Http/src/DefaultHttpContext.cs +++ b/src/Http/Http/src/DefaultHttpContext.cs @@ -13,6 +13,9 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Http { + /// + /// Represents an implementation of the HTTP Context class. + /// public sealed class DefaultHttpContext : HttpContext { // Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624 @@ -32,6 +35,9 @@ namespace Microsoft.AspNetCore.Http private DefaultConnectionInfo _connection; private DefaultWebSocketManager _websockets; + /// + /// Initializes a new instance of the class. + /// public DefaultHttpContext() : this(new FeatureCollection()) { @@ -40,6 +46,10 @@ namespace Microsoft.AspNetCore.Http Features.Set(new StreamResponseBodyFeature(Stream.Null)); } + /// + /// Initializes a new instance of the class with provided features. + /// + /// Initial set of features for the . public DefaultHttpContext(IFeatureCollection features) { _features.Initalize(features); @@ -47,6 +57,13 @@ namespace Microsoft.AspNetCore.Http _response = new DefaultHttpResponse(this); } + /// + /// Reinitialize the current instant of the class with features passed in. + /// + /// + /// This method allows the consumer to re-use the for another request, rather than having to allocate a new instance. + /// + /// The new set of features for the . public void Initialize(IFeatureCollection features) { var revision = features.Revision; @@ -57,6 +74,9 @@ namespace Microsoft.AspNetCore.Http _websockets?.Initialize(features, revision); } + /// + /// Uninitialize all the features in the . + /// public void Uninitialize() { _features = default; @@ -66,8 +86,20 @@ namespace Microsoft.AspNetCore.Http _websockets?.Uninitialize(); } + /// + /// Gets or set the for this instance. + /// + /// + /// + /// public FormOptions FormOptions { get; set; } + /// + /// Gets or sets the for this instance. + /// + /// + /// + /// public IServiceScopeFactory ServiceScopeFactory { get; set; } private IItemsFeature ItemsFeature => @@ -92,16 +124,22 @@ namespace Microsoft.AspNetCore.Http private IHttpRequestIdentifierFeature RequestIdentifierFeature => _features.Fetch(ref _features.Cache.RequestIdentifier, _newHttpRequestIdentifierFeature); + /// public override IFeatureCollection Features => _features.Collection ?? ContextDisposed(); + /// public override HttpRequest Request => _request; + /// public override HttpResponse Response => _response; - public override ConnectionInfo Connection => _connection ?? (_connection = new DefaultConnectionInfo(_features.Collection)); + /// + public override ConnectionInfo Connection => _connection ?? (_connection = new DefaultConnectionInfo(Features)); - public override WebSocketManager WebSockets => _websockets ?? (_websockets = new DefaultWebSocketManager(_features.Collection)); + /// + public override WebSocketManager WebSockets => _websockets ?? (_websockets = new DefaultWebSocketManager(Features)); + /// public override ClaimsPrincipal User { get @@ -117,30 +155,35 @@ namespace Microsoft.AspNetCore.Http set { HttpAuthenticationFeature.User = value; } } + /// public override IDictionary Items { get { return ItemsFeature.Items; } set { ItemsFeature.Items = value; } } + /// public override IServiceProvider RequestServices { get { return ServiceProvidersFeature.RequestServices; } set { ServiceProvidersFeature.RequestServices = value; } } + /// public override CancellationToken RequestAborted { get { return LifetimeFeature.RequestAborted; } set { LifetimeFeature.RequestAborted = value; } } + /// public override string TraceIdentifier { get { return RequestIdentifierFeature.TraceIdentifier; } set { RequestIdentifierFeature.TraceIdentifier = value; } } + /// public override ISession Session { get @@ -166,6 +209,7 @@ namespace Microsoft.AspNetCore.Http [EditorBrowsable(EditorBrowsableState.Never)] public HttpContext HttpContext => this; + /// public override void Abort() { LifetimeFeature.Abort(); diff --git a/src/Http/Http/src/Features/RequestServicesFeature.cs b/src/Http/Http/src/Features/RequestServicesFeature.cs index 6585127367..5a1a714998 100644 --- a/src/Http/Http/src/Features/RequestServicesFeature.cs +++ b/src/Http/Http/src/Features/RequestServicesFeature.cs @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Http.Features public void Dispose() { - DisposeAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + DisposeAsync().GetAwaiter().GetResult(); } } } diff --git a/src/Http/Http/src/HttpContextAccessor.cs b/src/Http/Http/src/HttpContextAccessor.cs index 286151029c..762e454c42 100644 --- a/src/Http/Http/src/HttpContextAccessor.cs +++ b/src/Http/Http/src/HttpContextAccessor.cs @@ -5,10 +5,14 @@ using System.Threading; namespace Microsoft.AspNetCore.Http { + /// + /// Provides an implementation of based on the current execution context. + /// public class HttpContextAccessor : IHttpContextAccessor { private static AsyncLocal _httpContextCurrent = new AsyncLocal(); + /// public HttpContext HttpContext { get diff --git a/src/Http/Http/src/HttpContextFactory.cs b/src/Http/Http/src/HttpContextFactory.cs index 3121c1704b..edddc658d3 100644 --- a/src/Http/Http/src/HttpContextFactory.cs +++ b/src/Http/Http/src/HttpContextFactory.cs @@ -8,6 +8,9 @@ using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Http { + /// + /// Represents methods used to create an HTTP context object. + /// [Obsolete("This is obsolete and will be removed in a future version. Use DefaultHttpContextFactory instead.")] public class HttpContextFactory : IHttpContextFactory { @@ -15,21 +18,41 @@ namespace Microsoft.AspNetCore.Http private readonly FormOptions _formOptions; private readonly IServiceScopeFactory _serviceScopeFactory; + /// + /// Initializes a new instance of the HttpContext class with options passed in. + /// + /// Options to set when instantianting the HTTP context object. public HttpContextFactory(IOptions formOptions) : this(formOptions, serviceScopeFactory: null) { } + /// + /// Initializes a new instance of the DefaultHttpContext class with options passed in. + /// + /// Options to set when instantianting the HTTP context object. + /// Factory object used to create the service scope for the HTTP context. public HttpContextFactory(IOptions formOptions, IServiceScopeFactory serviceScopeFactory) : this(formOptions, serviceScopeFactory, httpContextAccessor: null) { } + /// + /// Initializes a new instance of the DefaultHttpContext class with options passed in. + /// + /// Options to set when instantianting the HTTP context object. + /// Object to be used to access the HTTP context instance. public HttpContextFactory(IOptions formOptions, IHttpContextAccessor httpContextAccessor) : this(formOptions, serviceScopeFactory: null, httpContextAccessor: httpContextAccessor) { } + /// + /// Initializes a new instance of the DefaultHttpContext class with options passed in. + /// + /// Options to set when instantianting the HTTP context object. + /// Factory object used to create the service scope for the HTTP context. + /// Options to set when instantianting the Default HTTP context object. public HttpContextFactory(IOptions formOptions, IServiceScopeFactory serviceScopeFactory, IHttpContextAccessor httpContextAccessor) { if (formOptions == null) @@ -47,6 +70,10 @@ namespace Microsoft.AspNetCore.Http _httpContextAccessor = httpContextAccessor; } + /// + /// Initializes a new instance of the DefaultHttpContext class with options passed in. + /// + /// Options to set when instantianting the Default HTTP context object. public HttpContext Create(IFeatureCollection featureCollection) { if (featureCollection == null) @@ -66,6 +93,10 @@ namespace Microsoft.AspNetCore.Http return httpContext; } + /// + /// Sets the HTTP context object to null for garbage collection. + /// + /// HTTP context to dispose. public void Dispose(HttpContext httpContext) { if (_httpContextAccessor != null) diff --git a/src/Http/Http/src/Internal/ResponseCookies.cs b/src/Http/Http/src/Internal/ResponseCookies.cs index a8ed7dd66f..571df1068c 100644 --- a/src/Http/Http/src/Internal/ResponseCookies.cs +++ b/src/Http/Http/src/Internal/ResponseCookies.cs @@ -129,7 +129,7 @@ namespace Microsoft.AspNetCore.Http { Path = options.Path, Domain = options.Domain, - Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), + Expires = DateTimeOffset.UnixEpoch, Secure = options.Secure, HttpOnly = options.HttpOnly, SameSite = options.SameSite diff --git a/src/Http/Http/test/BindingAddressTests.cs b/src/Http/Http/test/BindingAddressTests.cs index 3e56f5a993..858aafeefb 100644 --- a/src/Http/Http/test/BindingAddressTests.cs +++ b/src/Http/Http/test/BindingAddressTests.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using System.Text; +using Microsoft.AspNetCore.Testing; +using Microsoft.AspNetCore.Testing.xunit; using Xunit; namespace Microsoft.AspNetCore.Http.Tests { @@ -32,6 +34,16 @@ namespace Microsoft.AspNetCore.Http.Tests Assert.Throws(() => BindingAddress.Parse(url)); } + [ConditionalTheory] + [InlineData("http://unix:/")] + [InlineData("http://unix:/c")] + [InlineData("http://unix:/wrong.path")] + [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX, SkipReason = "Windows has drive letters and volume separator (c:), testing this url on unix or osx provides completely different output.")] + public void FromUriThrowsForUrlsWithWrongFilePathOnWindows(string url) + { + Assert.Throws(() => BindingAddress.Parse(url)); + } + [Theory] [InlineData("://emptyscheme", "", "emptyscheme", 0, "", "://emptyscheme:0")] [InlineData("http://+", "http", "+", 80, "", "http://+:80")] @@ -50,11 +62,6 @@ namespace Microsoft.AspNetCore.Http.Tests [InlineData("http://foo:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "foo:", 80, "/tmp/kestrel-test.sock:5000/doesn't/matter", "http://foo::80/tmp/kestrel-test.sock:5000/doesn't/matter")] [InlineData("http://unix:foo/tmp/kestrel-test.sock", "http", "unix:foo", 80, "/tmp/kestrel-test.sock", "http://unix:foo:80/tmp/kestrel-test.sock")] [InlineData("http://unix:5000/tmp/kestrel-test.sock", "http", "unix", 5000, "/tmp/kestrel-test.sock", "http://unix:5000/tmp/kestrel-test.sock")] - [InlineData("http://unix:/tmp/kestrel-test.sock", "http", "unix:/tmp/kestrel-test.sock", 0, "", null)] - [InlineData("https://unix:/tmp/kestrel-test.sock", "https", "unix:/tmp/kestrel-test.sock", 0, "", null)] - [InlineData("http://unix:/tmp/kestrel-test.sock:", "http", "unix:/tmp/kestrel-test.sock", 0, "", "http://unix:/tmp/kestrel-test.sock")] - [InlineData("http://unix:/tmp/kestrel-test.sock:/", "http", "unix:/tmp/kestrel-test.sock", 0, "", "http://unix:/tmp/kestrel-test.sock")] - [InlineData("http://unix:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "unix:/tmp/kestrel-test.sock", 0, "5000/doesn't/matter", "http://unix:/tmp/kestrel-test.sock")] public void UrlsAreParsedCorrectly(string url, string scheme, string host, int port, string pathBase, string toString) { var serverAddress = BindingAddress.Parse(url); @@ -66,5 +73,43 @@ namespace Microsoft.AspNetCore.Http.Tests Assert.Equal(toString ?? url, serverAddress.ToString()); } + + [ConditionalTheory] + [InlineData("http://unix:/tmp/kestrel-test.sock", "http", "unix:/tmp/kestrel-test.sock", 0, "", null)] + [InlineData("https://unix:/tmp/kestrel-test.sock", "https", "unix:/tmp/kestrel-test.sock", 0, "", null)] + [InlineData("http://unix:/tmp/kestrel-test.sock:", "http", "unix:/tmp/kestrel-test.sock", 0, "", "http://unix:/tmp/kestrel-test.sock")] + [InlineData("http://unix:/tmp/kestrel-test.sock:/", "http", "unix:/tmp/kestrel-test.sock", 0, "", "http://unix:/tmp/kestrel-test.sock")] + [InlineData("http://unix:/tmp/kestrel-test.sock:5000/doesn't/matter", "http", "unix:/tmp/kestrel-test.sock", 0, "5000/doesn't/matter", "http://unix:/tmp/kestrel-test.sock")] + [OSSkipCondition(OperatingSystems.Windows)] + public void UnixSocketUrlsAreParsedCorrectlyOnUnix(string url, string scheme, string host, int port, string pathBase, string toString) + { + var serverAddress = BindingAddress.Parse(url); + + Assert.Equal(scheme, serverAddress.Scheme); + Assert.Equal(host, serverAddress.Host); + Assert.Equal(port, serverAddress.Port); + Assert.Equal(pathBase, serverAddress.PathBase); + + Assert.Equal(toString ?? url, serverAddress.ToString()); + } + + [ConditionalTheory] + [InlineData("http://unix:/c:/foo/bar/pipe.socket", "http", "unix:/c:/foo/bar/pipe.socket", 0, "", null)] + [InlineData("http://unix:/c:/foo/bar/pipe.socket:", "http", "unix:/c:/foo/bar/pipe.socket", 0, "", "http://unix:/c:/foo/bar/pipe.socket")] + [InlineData("http://unix:/c:/foo/bar/pipe.socket:/", "http", "unix:/c:/foo/bar/pipe.socket", 0, "", "http://unix:/c:/foo/bar/pipe.socket")] + [InlineData("http://unix:/c:/foo/bar/pipe.socket:5000/doesn't/matter", "http", "unix:/c:/foo/bar/pipe.socket", 0, "5000/doesn't/matter", "http://unix:/c:/foo/bar/pipe.socket")] + [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX, SkipReason = "Windows has drive letters and volume separator (c:), testing this url on unix or osx provides completely different output.")] + public void UnixSocketUrlsAreParsedCorrectlyOnWindows(string url, string scheme, string host, int port, string pathBase, string toString) + { + var serverAddress = BindingAddress.Parse(url); + + Assert.Equal(scheme, serverAddress.Scheme); + Assert.Equal(host, serverAddress.Host); + Assert.Equal(port, serverAddress.Port); + Assert.Equal(pathBase, serverAddress.PathBase); + + Assert.Equal(toString ?? url, serverAddress.ToString()); + } + } } diff --git a/src/Http/Owin/ref/Microsoft.AspNetCore.Owin.netcoreapp.cs b/src/Http/Owin/ref/Microsoft.AspNetCore.Owin.netcoreapp.cs index 84de949d34..7a3f19b969 100644 --- a/src/Http/Owin/ref/Microsoft.AspNetCore.Owin.netcoreapp.cs +++ b/src/Http/Owin/ref/Microsoft.AspNetCore.Owin.netcoreapp.cs @@ -60,12 +60,12 @@ namespace Microsoft.AspNetCore.Owin public partial class OwinEnvironmentFeature : Microsoft.AspNetCore.Owin.IOwinEnvironmentFeature { public OwinEnvironmentFeature() { } - public System.Collections.Generic.IDictionary Environment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Environment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class OwinFeatureCollection : Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature, Microsoft.AspNetCore.Http.Features.IFeatureCollection, Microsoft.AspNetCore.Http.Features.IHttpConnectionFeature, Microsoft.AspNetCore.Http.Features.IHttpRequestFeature, Microsoft.AspNetCore.Http.Features.IHttpRequestIdentifierFeature, Microsoft.AspNetCore.Http.Features.IHttpRequestLifetimeFeature, Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature, Microsoft.AspNetCore.Http.Features.IHttpResponseFeature, Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature, Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature, Microsoft.AspNetCore.Owin.IOwinEnvironmentFeature, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable { public OwinFeatureCollection(System.Collections.Generic.IDictionary environment) { } - public System.Collections.Generic.IDictionary Environment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Environment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool IsReadOnly { get { throw null; } } public object this[System.Type key] { get { throw null; } set { } } System.Security.Claims.ClaimsPrincipal Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature.User { get { throw null; } set { } } @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Owin bool Microsoft.AspNetCore.Http.Features.IHttpWebSocketFeature.IsWebSocketRequest { get { throw null; } } System.Security.Cryptography.X509Certificates.X509Certificate2 Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature.ClientCertificate { get { throw null; } set { } } public int Revision { get { throw null; } } - public bool SupportsWebSockets { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SupportsWebSockets { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Dispose() { } public object Get(System.Type key) { throw null; } public System.Collections.Generic.IEnumerator> GetEnumerator() { throw null; } diff --git a/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs b/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs index fbd15beb8b..6aea07474a 100644 --- a/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs +++ b/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs @@ -38,15 +38,15 @@ namespace Microsoft.AspNetCore.Routing public partial class LinkOptions { public LinkOptions() { } - public bool? AppendTrailingSlash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? LowercaseQueryStrings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? LowercaseUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool? AppendTrailingSlash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? LowercaseQueryStrings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? LowercaseUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RouteContext { public RouteContext(Microsoft.AspNetCore.Http.HttpContext httpContext) { } - public Microsoft.AspNetCore.Http.RequestDelegate Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.RequestDelegate Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.RouteData RouteData { get { throw null; } set { } } } public partial class RouteData @@ -62,6 +62,7 @@ namespace Microsoft.AspNetCore.Routing public readonly partial struct RouteDataSnapshot { private readonly object _dummy; + private readonly int _dummyPrimitive; public RouteDataSnapshot(Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens, System.Collections.Generic.IList routers, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { throw null; } public void Restore() { } } @@ -80,17 +81,17 @@ namespace Microsoft.AspNetCore.Routing { public VirtualPathContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { } public VirtualPathContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string routeName) { } - public Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class VirtualPathData { public VirtualPathData(Microsoft.AspNetCore.Routing.IRouter router, string virtualPath) { } public VirtualPathData(Microsoft.AspNetCore.Routing.IRouter router, string virtualPath, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens) { } public Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { get { throw null; } } - public Microsoft.AspNetCore.Routing.IRouter Router { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.IRouter Router { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string VirtualPath { get { throw null; } set { } } } } diff --git a/src/Http/Routing.Abstractions/src/LinkOptions.cs b/src/Http/Routing.Abstractions/src/LinkOptions.cs index a5bd0547f0..5c1e377bb1 100644 --- a/src/Http/Routing.Abstractions/src/LinkOptions.cs +++ b/src/Http/Routing.Abstractions/src/LinkOptions.cs @@ -6,13 +6,13 @@ namespace Microsoft.AspNetCore.Routing public class LinkOptions { /// - /// Gets or sets a value indicating whether all generated paths URLs are lower-case. + /// Gets or sets a value indicating whether all generated paths URLs are lowercase. /// Use to configure the behavior for query strings. /// public bool? LowercaseUrls { get; set; } /// - /// Gets or sets a value indicating whether a generated query strings are lower-case. + /// Gets or sets a value indicating whether a generated query strings are lowercase. /// This property will be unless is also true. /// public bool? LowercaseQueryStrings { get; set; } diff --git a/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs b/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs index 81f59873b9..25c554c639 100644 --- a/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs +++ b/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Routing public sealed partial class DataTokensMetadata : Microsoft.AspNetCore.Routing.IDataTokensMetadata { public DataTokensMetadata(System.Collections.Generic.IReadOnlyDictionary dataTokens) { } - public System.Collections.Generic.IReadOnlyDictionary DataTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary DataTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class DefaultEndpointDataSource : Microsoft.AspNetCore.Routing.EndpointDataSource { @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Routing public partial class EndpointNameMetadata : Microsoft.AspNetCore.Routing.IEndpointNameMetadata { public EndpointNameMetadata(string endpointName) { } - public string EndpointName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string EndpointName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)] [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString(),nq}")] @@ -94,15 +94,15 @@ namespace Microsoft.AspNetCore.Routing { public HostAttribute(string host) { } public HostAttribute(params string[] hosts) { } - public System.Collections.Generic.IReadOnlyList Hosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Hosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString(),nq}")] public sealed partial class HttpMethodMetadata : Microsoft.AspNetCore.Routing.IHttpMethodMetadata { public HttpMethodMetadata(System.Collections.Generic.IEnumerable httpMethods) { } public HttpMethodMetadata(System.Collections.Generic.IEnumerable httpMethods, bool acceptCorsPreflight) { } - public bool AcceptCorsPreflight { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList HttpMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AcceptCorsPreflight { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList HttpMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IDataTokensMetadata { @@ -239,12 +239,12 @@ namespace Microsoft.AspNetCore.Routing public abstract partial class RouteBase : Microsoft.AspNetCore.Routing.INamedRouter, Microsoft.AspNetCore.Routing.IRouter { public RouteBase(string template, string name, Microsoft.AspNetCore.Routing.IInlineConstraintResolver constraintResolver, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults, System.Collections.Generic.IDictionary constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens) { } - protected virtual Microsoft.AspNetCore.Routing.IInlineConstraintResolver ConstraintResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.Collections.Generic.IDictionary Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public virtual Microsoft.AspNetCore.Routing.Template.RouteTemplate ParsedTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + protected virtual Microsoft.AspNetCore.Routing.IInlineConstraintResolver ConstraintResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.Collections.Generic.IDictionary Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public virtual Microsoft.AspNetCore.Routing.Template.RouteTemplate ParsedTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } protected static System.Collections.Generic.IDictionary GetConstraints(Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver, Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, System.Collections.Generic.IDictionary constraints) { throw null; } protected static Microsoft.AspNetCore.Routing.RouteValueDictionary GetDefaults(Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults) { throw null; } public virtual Microsoft.AspNetCore.Routing.VirtualPathData GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; } @@ -257,10 +257,10 @@ namespace Microsoft.AspNetCore.Routing { public RouteBuilder(Microsoft.AspNetCore.Builder.IApplicationBuilder applicationBuilder) { } public RouteBuilder(Microsoft.AspNetCore.Builder.IApplicationBuilder applicationBuilder, Microsoft.AspNetCore.Routing.IRouter defaultHandler) { } - public Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.IRouter DefaultHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Routes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.IServiceProvider ServiceProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.IRouter DefaultHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Routes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.IServiceProvider ServiceProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.IRouter Build() { throw null; } } public partial class RouteCollection : Microsoft.AspNetCore.Routing.IRouteCollection, Microsoft.AspNetCore.Routing.IRouter @@ -293,14 +293,14 @@ namespace Microsoft.AspNetCore.Routing public sealed partial class RouteEndpoint : Microsoft.AspNetCore.Http.Endpoint { public RouteEndpoint(Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, Microsoft.AspNetCore.Routing.Patterns.RoutePattern routePattern, int order, Microsoft.AspNetCore.Http.EndpointMetadataCollection metadata, string displayName) : base (default(Microsoft.AspNetCore.Http.RequestDelegate), default(Microsoft.AspNetCore.Http.EndpointMetadataCollection), default(string)) { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.Patterns.RoutePattern RoutePattern { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.Patterns.RoutePattern RoutePattern { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class RouteEndpointBuilder : Microsoft.AspNetCore.Builder.EndpointBuilder { public RouteEndpointBuilder(Microsoft.AspNetCore.Http.RequestDelegate requestDelegate, Microsoft.AspNetCore.Routing.Patterns.RoutePattern routePattern, int order) { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Patterns.RoutePattern RoutePattern { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Patterns.RoutePattern RoutePattern { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override Microsoft.AspNetCore.Http.Endpoint Build() { throw null; } } public partial class RouteHandler : Microsoft.AspNetCore.Routing.IRouteHandler, Microsoft.AspNetCore.Routing.IRouter @@ -314,16 +314,16 @@ namespace Microsoft.AspNetCore.Routing public sealed partial class RouteNameMetadata : Microsoft.AspNetCore.Routing.IRouteNameMetadata { public RouteNameMetadata(string routeName) { } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class RouteOptions { public RouteOptions() { } - public bool AppendTrailingSlash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AppendTrailingSlash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.IDictionary ConstraintMap { get { throw null; } set { } } - public bool LowercaseQueryStrings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool LowercaseUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressCheckForUnhandledSecurityMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool LowercaseQueryStrings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool LowercaseUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressCheckForUnhandledSecurityMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RouteValueEqualityComparer : System.Collections.Generic.IEqualityComparer { @@ -335,14 +335,14 @@ namespace Microsoft.AspNetCore.Routing public partial class RouteValuesAddress { public RouteValuesAddress() { } - public Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary ExplicitValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary ExplicitValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RoutingFeature : Microsoft.AspNetCore.Routing.IRoutingFeature { public RoutingFeature() { } - public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public sealed partial class SuppressLinkGenerationMetadata : Microsoft.AspNetCore.Routing.ISuppressLinkGenerationMetadata { @@ -369,7 +369,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints public partial class CompositeRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public CompositeRouteConstraint(System.Collections.Generic.IEnumerable constraints) { } - public System.Collections.Generic.IEnumerable Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class DateTimeRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint @@ -405,7 +405,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints public partial class HttpMethodRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public HttpMethodRouteConstraint(params string[] allowedMethods) { } - public System.Collections.Generic.IList AllowedMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList AllowedMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class IntRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint @@ -417,8 +417,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints { public LengthRouteConstraint(int length) { } public LengthRouteConstraint(int minLength, int maxLength) { } - public int MaxLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int MinLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int MaxLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int MinLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class LongRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint @@ -429,25 +429,25 @@ namespace Microsoft.AspNetCore.Routing.Constraints public partial class MaxLengthRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public MaxLengthRouteConstraint(int maxLength) { } - public int MaxLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int MaxLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class MaxRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public MaxRouteConstraint(long max) { } - public long Max { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public long Max { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class MinLengthRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public MinLengthRouteConstraint(int minLength) { } - public int MinLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int MinLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class MinRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public MinRouteConstraint(long min) { } - public long Min { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public long Min { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class NonFileNameRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint @@ -458,14 +458,14 @@ namespace Microsoft.AspNetCore.Routing.Constraints public partial class OptionalRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public OptionalRouteConstraint(Microsoft.AspNetCore.Routing.IRouteConstraint innerConstraint) { } - public Microsoft.AspNetCore.Routing.IRouteConstraint InnerConstraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Routing.IRouteConstraint InnerConstraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class RangeRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint { public RangeRouteConstraint(long min, long max) { } - public long Max { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public long Min { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public long Max { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public long Min { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class RegexInlineRouteConstraint : Microsoft.AspNetCore.Routing.Constraints.RegexRouteConstraint @@ -476,7 +476,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints { public RegexRouteConstraint(string regexPattern) { } public RegexRouteConstraint(System.Text.RegularExpressions.Regex regex) { } - public System.Text.RegularExpressions.Regex Constraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Text.RegularExpressions.Regex Constraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) { throw null; } } public partial class RequiredRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy, Microsoft.AspNetCore.Routing.IRouteConstraint @@ -515,9 +515,9 @@ namespace Microsoft.AspNetCore.Routing.Matching { private object _dummy; private int _dummyPrimitive; - public Microsoft.AspNetCore.Http.Endpoint Endpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Score { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.Endpoint Endpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Score { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class EndpointMetadataComparer : System.Collections.Generic.IComparer { @@ -540,8 +540,8 @@ namespace Microsoft.AspNetCore.Routing.Matching public sealed partial class HostMatcherPolicy : Microsoft.AspNetCore.Routing.MatcherPolicy, Microsoft.AspNetCore.Routing.Matching.IEndpointComparerPolicy, Microsoft.AspNetCore.Routing.Matching.IEndpointSelectorPolicy, Microsoft.AspNetCore.Routing.Matching.INodeBuilderPolicy { public HostMatcherPolicy() { } - public System.Collections.Generic.IComparer Comparer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IComparer Comparer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates) { throw null; } public Microsoft.AspNetCore.Routing.Matching.PolicyJumpTable BuildJumpTable(int exitDestination, System.Collections.Generic.IReadOnlyList edges) { throw null; } public System.Collections.Generic.IReadOnlyList GetEdges(System.Collections.Generic.IReadOnlyList endpoints) { throw null; } @@ -585,16 +585,17 @@ namespace Microsoft.AspNetCore.Routing.Matching private readonly object _dummy; private readonly int _dummyPrimitive; public PolicyJumpTableEdge(object state, int destination) { throw null; } - public int Destination { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object State { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int Destination { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object State { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct PolicyNodeEdge { private readonly object _dummy; + private readonly int _dummyPrimitive; public PolicyNodeEdge(object state, System.Collections.Generic.IReadOnlyList endpoints) { throw null; } - public System.Collections.Generic.IReadOnlyList Endpoints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object State { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Endpoints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object State { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Routing.Patterns @@ -604,20 +605,20 @@ namespace Microsoft.AspNetCore.Routing.Patterns { internal RoutePattern() { } public static readonly object RequiredValueAny; - public System.Collections.Generic.IReadOnlyDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public decimal InboundPrecedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public decimal OutboundPrecedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary> ParameterPolicies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList PathSegments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RawText { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary RequiredValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public decimal InboundPrecedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public decimal OutboundPrecedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary> ParameterPolicies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList PathSegments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RawText { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary RequiredValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart GetParameter(string name) { throw null; } } public sealed partial class RoutePatternException : System.Exception { public RoutePatternException(string pattern, string message) { } - public string Pattern { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Pattern { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } public static partial class RoutePatternFactory @@ -652,7 +653,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns public sealed partial class RoutePatternLiteralPart : Microsoft.AspNetCore.Routing.Patterns.RoutePatternPart { internal RoutePatternLiteralPart() { } - public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum RoutePatternParameterKind { @@ -664,20 +665,20 @@ namespace Microsoft.AspNetCore.Routing.Patterns public sealed partial class RoutePatternParameterPart : Microsoft.AspNetCore.Routing.Patterns.RoutePatternPart { internal RoutePatternParameterPart() { } - public object Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EncodeSlashes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EncodeSlashes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool IsCatchAll { get { throw null; } } public bool IsOptional { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterKind ParameterKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList ParameterPolicies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterKind ParameterKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList ParameterPolicies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString()}")] public sealed partial class RoutePatternParameterPolicyReference { internal RoutePatternParameterPolicyReference() { } - public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.IParameterPolicy ParameterPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.IParameterPolicy ParameterPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class RoutePatternPart { @@ -685,7 +686,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns public bool IsLiteral { get { throw null; } } public bool IsParameter { get { throw null; } } public bool IsSeparator { get { throw null; } } - public Microsoft.AspNetCore.Routing.Patterns.RoutePatternPartKind PartKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Routing.Patterns.RoutePatternPartKind PartKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum RoutePatternPartKind { @@ -698,13 +699,13 @@ namespace Microsoft.AspNetCore.Routing.Patterns { internal RoutePatternPathSegment() { } public bool IsSimple { get { throw null; } } - public System.Collections.Generic.IReadOnlyList Parts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Parts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString()}")] public sealed partial class RoutePatternSeparatorPart : Microsoft.AspNetCore.Routing.Patterns.RoutePatternPart { internal RoutePatternSeparatorPart() { } - public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class RoutePatternTransformer { @@ -718,7 +719,7 @@ namespace Microsoft.AspNetCore.Routing.Template { public InlineConstraint(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPolicyReference other) { } public InlineConstraint(string constraint) { } - public string Constraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Constraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class RoutePrecedence { @@ -730,9 +731,9 @@ namespace Microsoft.AspNetCore.Routing.Template { public RouteTemplate(Microsoft.AspNetCore.Routing.Patterns.RoutePattern other) { } public RouteTemplate(string template, System.Collections.Generic.List segments) { } - public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Segments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string TemplateText { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Segments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string TemplateText { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.Template.TemplatePart GetParameter(string name) { throw null; } public Microsoft.AspNetCore.Routing.Template.TemplateSegment GetSegment(int index) { throw null; } public Microsoft.AspNetCore.Routing.Patterns.RoutePattern ToRoutePattern() { throw null; } @@ -754,8 +755,8 @@ namespace Microsoft.AspNetCore.Routing.Template public partial class TemplateMatcher { public TemplateMatcher(Microsoft.AspNetCore.Routing.Template.RouteTemplate template, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults) { } - public Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.Template.RouteTemplate Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.Template.RouteTemplate Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool TryMatch(Microsoft.AspNetCore.Http.PathString path, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { throw null; } } public static partial class TemplateParser @@ -767,15 +768,15 @@ namespace Microsoft.AspNetCore.Routing.Template { public TemplatePart() { } public TemplatePart(Microsoft.AspNetCore.Routing.Patterns.RoutePatternPart other) { } - public object DefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IEnumerable InlineConstraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsCatchAll { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsLiteral { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsOptional { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsOptionalSeperator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Text { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object DefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IEnumerable InlineConstraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsCatchAll { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsLiteral { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsOptional { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsOptionalSeperator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Text { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Routing.Template.TemplatePart CreateLiteral(string text) { throw null; } public static Microsoft.AspNetCore.Routing.Template.TemplatePart CreateParameter(string name, bool isCatchAll, bool isOptional, object defaultValue, System.Collections.Generic.IEnumerable inlineConstraints) { throw null; } public Microsoft.AspNetCore.Routing.Patterns.RoutePatternPart ToRoutePatternPart() { throw null; } @@ -786,14 +787,14 @@ namespace Microsoft.AspNetCore.Routing.Template public TemplateSegment() { } public TemplateSegment(Microsoft.AspNetCore.Routing.Patterns.RoutePatternPathSegment other) { } public bool IsSimple { get { throw null; } } - public System.Collections.Generic.List Parts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.List Parts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.Patterns.RoutePatternPathSegment ToRoutePatternPathSegment() { throw null; } } public partial class TemplateValuesResult { public TemplateValuesResult() { } - public Microsoft.AspNetCore.Routing.RouteValueDictionary AcceptedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary CombinedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary AcceptedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary CombinedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Routing.Tree @@ -802,44 +803,44 @@ namespace Microsoft.AspNetCore.Routing.Tree public partial class InboundMatch { public InboundMatch() { } - public Microsoft.AspNetCore.Routing.Tree.InboundRouteEntry Entry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Template.TemplateMatcher TemplateMatcher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.Tree.InboundRouteEntry Entry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Template.TemplateMatcher TemplateMatcher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class InboundRouteEntry { public InboundRouteEntry() { } - public System.Collections.Generic.IDictionary Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.IRouter Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public decimal Precedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Template.RouteTemplate RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.IRouter Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public decimal Precedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Template.RouteTemplate RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class OutboundMatch { public OutboundMatch() { } - public Microsoft.AspNetCore.Routing.Tree.OutboundRouteEntry Entry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Template.TemplateBinder TemplateBinder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.Tree.OutboundRouteEntry Entry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Template.TemplateBinder TemplateBinder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class OutboundRouteEntry { public OutboundRouteEntry() { } - public System.Collections.Generic.IDictionary Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object Data { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.IRouter Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public decimal Precedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RequiredLinkValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Template.RouteTemplate RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object Data { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.IRouter Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public decimal Precedence { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RequiredLinkValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Template.RouteTemplate RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TreeRouteBuilder { internal TreeRouteBuilder() { } - public System.Collections.Generic.IList InboundEntries { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList OutboundEntries { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList InboundEntries { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList OutboundEntries { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.Tree.TreeRouter Build() { throw null; } public Microsoft.AspNetCore.Routing.Tree.TreeRouter Build(int version) { throw null; } public void Clear() { } @@ -850,7 +851,7 @@ namespace Microsoft.AspNetCore.Routing.Tree { internal TreeRouter() { } public static readonly string RouteGroupKey; - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Routing.VirtualPathData GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; } @@ -859,20 +860,20 @@ namespace Microsoft.AspNetCore.Routing.Tree public partial class UrlMatchingNode { public UrlMatchingNode(int length) { } - public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode CatchAlls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode ConstrainedCatchAlls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode ConstrainedParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Depth { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsCatchAll { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.Dictionary Literals { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.List Matches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode CatchAlls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode ConstrainedCatchAlls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode ConstrainedParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Depth { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsCatchAll { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.Dictionary Literals { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.List Matches { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UrlMatchingTree { public UrlMatchingTree(int order) { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode Root { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.Tree.UrlMatchingNode Root { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Http/Routing/src/CompositeEndpointDataSource.cs b/src/Http/Routing/src/CompositeEndpointDataSource.cs index e6b1c0a19a..008ad09a9c 100644 --- a/src/Http/Routing/src/CompositeEndpointDataSource.cs +++ b/src/Http/Routing/src/CompositeEndpointDataSource.cs @@ -165,7 +165,7 @@ namespace Microsoft.AspNetCore.Routing template = string.IsNullOrEmpty(template) ? "\"\"" : template; sb.Append(template); sb.Append(", Defaults: new { "); - sb.Append(string.Join(", ", FormatValues(routeEndpoint.RoutePattern.Defaults))); + sb.AppendJoin(", ", FormatValues(routeEndpoint.RoutePattern.Defaults)); sb.Append(" }"); var routeNameMetadata = routeEndpoint.Metadata.GetMetadata(); sb.Append(", Route Name: "); @@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.Routing if (routeValues.Count > 0) { sb.Append(", Required Values: new { "); - sb.Append(string.Join(", ", FormatValues(routeValues))); + sb.AppendJoin(", ", FormatValues(routeValues)); sb.Append(" }"); } sb.Append(", Order: "); @@ -184,7 +184,7 @@ namespace Microsoft.AspNetCore.Routing if (httpMethodMetadata != null) { sb.Append(", Http Methods: "); - sb.Append(string.Join(", ", httpMethodMetadata.HttpMethods)); + sb.AppendJoin(", ", httpMethodMetadata.HttpMethods); } sb.Append(", Display Name: "); sb.Append(routeEndpoint.DisplayName); diff --git a/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs b/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs index 18fbec0c19..ea20e81419 100644 --- a/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs +++ b/src/Http/Routing/src/Constraints/HttpMethodRouteConstraint.cs @@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints // the HTTP GET-specific route will be used for URI generation, which might have undesired behavior. // // To prevent this, a user might call GetVirtualPath(..., { httpMethod = "POST" }) to - // signal that he is generating a URI that will be used for an HTTP POST, so he wants the URI + // signal that they are generating a URI that will be used for an HTTP POST, so they want the URI // generation to be performed by the (b) route instead of the (a) route, consistent with what would // happen on incoming requests. if (!values.TryGetValue(routeKey, out var obj)) diff --git a/src/Http/Routing/src/EndpointMiddleware.cs b/src/Http/Routing/src/EndpointMiddleware.cs index 9b06b673ad..0e11e560b7 100644 --- a/src/Http/Routing/src/EndpointMiddleware.cs +++ b/src/Http/Routing/src/EndpointMiddleware.cs @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Routing throw new InvalidOperationException($"Endpoint {endpoint.DisplayName} contains CORS metadata, " + "but a middleware was not found that supports CORS." + Environment.NewLine + - "Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...)."); + "Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. The call to app.UseCors() must appear between app.UseRouting() and app.UseEndpoints(...)."); } private static class Log diff --git a/src/Http/Routing/src/Matching/DfaNode.cs b/src/Http/Routing/src/Matching/DfaNode.cs index f3f916b8e5..602a48a0e2 100644 --- a/src/Http/Routing/src/Matching/DfaNode.cs +++ b/src/Http/Routing/src/Matching/DfaNode.cs @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Routing.Matching builder.Append(" c: "); if (Literals != null) { - builder.Append(string.Join(", ", Literals.Select(kvp => $"{kvp.Key}->({FormatNode(kvp.Value)})"))); + builder.AppendJoin(", ", Literals.Select(kvp => $"{kvp.Key}->({FormatNode(kvp.Value)})")); } return builder.ToString(); diff --git a/src/Http/Routing/src/Matching/DictionaryJumpTable.cs b/src/Http/Routing/src/Matching/DictionaryJumpTable.cs index 27445737e9..644f9c95ac 100644 --- a/src/Http/Routing/src/Matching/DictionaryJumpTable.cs +++ b/src/Http/Routing/src/Matching/DictionaryJumpTable.cs @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var builder = new StringBuilder(); builder.Append("{ "); - builder.Append(string.Join(", ", _dictionary.Select(kvp => $"{kvp.Key}: {kvp.Value}"))); + builder.AppendJoin(", ", _dictionary.Select(kvp => $"{kvp.Key}: {kvp.Value}")); builder.Append("$+: "); builder.Append(_defaultDestination); diff --git a/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs b/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs index b6389ab76a..55ee196e8b 100644 --- a/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs +++ b/src/Http/Routing/src/Matching/HttpMethodMatcherPolicy.cs @@ -385,7 +385,7 @@ namespace Microsoft.AspNetCore.Routing.Matching context.Response.StatusCode = 405; // Prevent ArgumentException from duplicate key if header already added, such as when the - // request is re-executed by an error handler (see https://github.com/aspnet/AspNetCore/issues/6415) + // request is re-executed by an error handler (see https://github.com/dotnet/aspnetcore/issues/6415) context.Response.Headers[HeaderNames.Allow] = allow; return Task.CompletedTask; diff --git a/src/Http/Routing/src/Matching/LinearSearchJumpTable.cs b/src/Http/Routing/src/Matching/LinearSearchJumpTable.cs index 58f8b3d01d..37d5805c63 100644 --- a/src/Http/Routing/src/Matching/LinearSearchJumpTable.cs +++ b/src/Http/Routing/src/Matching/LinearSearchJumpTable.cs @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Routing.Matching var builder = new StringBuilder(); builder.Append("{ "); - builder.Append(string.Join(", ", _entries.Select(e => $"{e.text}: {e.destination}"))); + builder.AppendJoin(", ", _entries.Select(e => $"{e.text}: {e.destination}")); builder.Append("$+: "); builder.Append(_defaultDestination); diff --git a/src/Http/Routing/src/RouteBase.cs b/src/Http/Routing/src/RouteBase.cs index c4b86692ff..019b7a7f7f 100644 --- a/src/Http/Routing/src/RouteBase.cs +++ b/src/Http/Routing/src/RouteBase.cs @@ -265,7 +265,7 @@ namespace Microsoft.AspNetCore.Routing { if (_logger != null) { - // Multiple threads might have tried to accquire the lock at the same time. Technically + // Multiple threads might have tried to acquire the lock at the same time. Technically // there is nothing wrong if things get reinitialized by a second thread, but its easy // to prevent by just rechecking and returning here. return; diff --git a/src/Http/Routing/src/RouteConstraintBuilder.cs b/src/Http/Routing/src/RouteConstraintBuilder.cs index 14c4e12f3c..9ff60e52a9 100644 --- a/src/Http/Routing/src/RouteConstraintBuilder.cs +++ b/src/Http/Routing/src/RouteConstraintBuilder.cs @@ -90,8 +90,8 @@ namespace Microsoft.AspNetCore.Routing /// /// If the is a string, it will be converted to a . /// - /// For example, the string Product[0-9]+ will be converted to the regular expression - /// ^(Product[0-9]+). See for more details. + /// For example, the string Product[0-9]+ will be converted to the regular expression + /// ^(Product[0-9]+). See for more details. /// public void AddConstraint(string key, object value) { diff --git a/src/Http/Routing/src/RouteOptions.cs b/src/Http/Routing/src/RouteOptions.cs index 3d06d5525b..dcff5482e7 100644 --- a/src/Http/Routing/src/RouteOptions.cs +++ b/src/Http/Routing/src/RouteOptions.cs @@ -27,13 +27,13 @@ namespace Microsoft.AspNetCore.Routing } /// - /// Gets or sets a value indicating whether all generated paths URLs are lower-case. + /// Gets or sets a value indicating whether all generated paths URLs are lowercase. /// Use to configure the behavior for query strings. /// public bool LowercaseUrls { get; set; } /// - /// Gets or sets a value indicating whether a generated query strings are lower-case. + /// Gets or sets a value indicating whether a generated query strings are lowercase. /// This property will not be used unless is also true. /// public bool LowercaseQueryStrings { get; set; } diff --git a/src/Http/Routing/src/Tree/LinkGenerationDecisionTree.cs b/src/Http/Routing/src/Tree/LinkGenerationDecisionTree.cs index 568c377745..6aa8b84867 100644 --- a/src/Http/Routing/src/Tree/LinkGenerationDecisionTree.cs +++ b/src/Http/Routing/src/Tree/LinkGenerationDecisionTree.cs @@ -248,7 +248,7 @@ namespace Microsoft.AspNetCore.Routing.Tree } sb.Append(matchesSb.ToString()); sb.Append(" (Matches: "); - sb.Append(string.Join(", ", node.Matches.Select(m => m.Entry.RouteTemplate.TemplateText))); + sb.AppendJoin(", ", node.Matches.Select(m => m.Entry.RouteTemplate.TemplateText)); sb.AppendLine(")"); } diff --git a/src/Http/Routing/test/FunctionalTests/EndpointRoutingIntegrationTest.cs b/src/Http/Routing/test/FunctionalTests/EndpointRoutingIntegrationTest.cs index 232d648714..f0fa4a4f59 100644 --- a/src/Http/Routing/test/FunctionalTests/EndpointRoutingIntegrationTest.cs +++ b/src/Http/Routing/test/FunctionalTests/EndpointRoutingIntegrationTest.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Routing.FunctionalTests private static readonly string CORSErrorMessage = "Endpoint / contains CORS metadata, but a middleware was not found that supports CORS." + Environment.NewLine + "Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. " + - "The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...)."; + "The call to app.UseCors() must appear between app.UseRouting() and app.UseEndpoints(...)."; [Fact] public async Task AuthorizationMiddleware_WhenNoAuthMetadataIsConfigured() diff --git a/src/Http/Routing/test/UnitTests/EndpointMiddlewareTest.cs b/src/Http/Routing/test/UnitTests/EndpointMiddlewareTest.cs index 7a638e7e8c..75ddf41453 100644 --- a/src/Http/Routing/test/UnitTests/EndpointMiddlewareTest.cs +++ b/src/Http/Routing/test/UnitTests/EndpointMiddlewareTest.cs @@ -199,7 +199,7 @@ namespace Microsoft.AspNetCore.Routing var expected = "Endpoint Test contains CORS metadata, but a middleware was not found that supports CORS." + Environment.NewLine + "Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. " + - "The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...)."; + "The call to app.UseCors() must appear between app.UseRouting() and app.UseEndpoints(...)."; var httpContext = new DefaultHttpContext { RequestServices = new ServiceProvider() diff --git a/src/Http/Routing/test/UnitTests/Matching/HostMatcherPolicyIntegrationTestBase.cs b/src/Http/Routing/test/UnitTests/Matching/HostMatcherPolicyIntegrationTestBase.cs index e3cb4732b6..0e9d6da6c0 100644 --- a/src/Http/Routing/test/UnitTests/Matching/HostMatcherPolicyIntegrationTestBase.cs +++ b/src/Http/Routing/test/UnitTests/Matching/HostMatcherPolicyIntegrationTestBase.cs @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Routing.Matching } [Fact] - public async Task Match_HostWithWildcard() + public async Task Match_HostWithWildcard_Unicode() { // Arrange var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", }); @@ -114,7 +114,23 @@ namespace Microsoft.AspNetCore.Routing.Matching } [Fact] - public async Task Match_HostWithWildcard_Unicode() + public async Task Match_HostWithWildcard_NoSubdomain() + { + // Arrange + var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", }); + + var matcher = CreateMatcher(endpoint); + var httpContext = CreateContext("/hello", "contoso.com:8080"); + + // Act + await matcher.MatchAsync(httpContext); + + // Assert + MatcherAssert.AssertNotMatch(httpContext); + } + + [Fact] + public async Task Match_HostWithWildcard_Subdomain() { // Arrange var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", }); @@ -129,6 +145,54 @@ namespace Microsoft.AspNetCore.Routing.Matching MatcherAssert.AssertMatch(httpContext, endpoint); } + [Fact] + public async Task Match_HostWithWildcard_MultipleSubdomains() + { + // Arrange + var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", }); + + var matcher = CreateMatcher(endpoint); + var httpContext = CreateContext("/hello", "www.blog.contoso.com:8080"); + + // Act + await matcher.MatchAsync(httpContext); + + // Assert + MatcherAssert.AssertMatch(httpContext, endpoint); + } + + [Fact] + public async Task Match_HostWithWildcard_PrefixNotInSubdomain() + { + // Arrange + var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", }); + + var matcher = CreateMatcher(endpoint); + var httpContext = CreateContext("/hello", "mycontoso.com:8080"); + + // Act + await matcher.MatchAsync(httpContext); + + // Assert + MatcherAssert.AssertNotMatch(httpContext); + } + + [Fact] + public async Task Match_HostAndHostWithWildcard_NoSubdomain() + { + // Arrange + var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:8080", "*.contoso.com:8080", }); + + var matcher = CreateMatcher(endpoint); + var httpContext = CreateContext("/hello", "contoso.com:8080"); + + // Act + await matcher.MatchAsync(httpContext); + + // Assert + MatcherAssert.AssertMatch(httpContext, endpoint); + } + [Fact] public async Task Match_Host_CaseInsensitive() { diff --git a/src/Http/Routing/test/UnitTests/Matching/HttpMethodMatcherPolicyIntegrationTestBase.cs b/src/Http/Routing/test/UnitTests/Matching/HttpMethodMatcherPolicyIntegrationTestBase.cs index bd477bb4d3..5f219e329a 100644 --- a/src/Http/Routing/test/UnitTests/Matching/HttpMethodMatcherPolicyIntegrationTestBase.cs +++ b/src/Http/Routing/test/UnitTests/Matching/HttpMethodMatcherPolicyIntegrationTestBase.cs @@ -290,7 +290,7 @@ namespace Microsoft.AspNetCore.Routing.Matching MatcherAssert.AssertMatch(httpContext, endpoint2, ignoreValues: true); } - [Fact] // See https://github.com/aspnet/AspNetCore/issues/6415 + [Fact] // See https://github.com/dotnet/aspnetcore/issues/6415 public async Task NotMatch_HttpMethod_Returns405Endpoint_ReExecute() { // Arrange diff --git a/src/Http/Routing/test/UnitTests/Template/TemplateBinderTests.cs b/src/Http/Routing/test/UnitTests/Template/TemplateBinderTests.cs index 00eafa490c..1aa2c5ad8b 100644 --- a/src/Http/Routing/test/UnitTests/Template/TemplateBinderTests.cs +++ b/src/Http/Routing/test/UnitTests/Template/TemplateBinderTests.cs @@ -1380,7 +1380,7 @@ namespace Microsoft.AspNetCore.Routing.Template.Tests Assert.Equal(expected, boundTemplate); } - // Regression test for aspnet/AspNetCore#4212 + // Regression test for dotnet/aspnetcore#4212 // // An ambient value should be used to satisfy a required value even if if we're discarding // ambient values. diff --git a/src/Http/Routing/test/testassets/Benchmarks/benchmarks.json b/src/Http/Routing/test/testassets/Benchmarks/benchmarks.json index c0735fa032..48622c7968 100644 --- a/src/Http/Routing/test/testassets/Benchmarks/benchmarks.json +++ b/src/Http/Routing/test/testassets/Benchmarks/benchmarks.json @@ -7,7 +7,7 @@ "PipelineDepth": 16 }, "Source": { - "Repository": "https://github.com/aspnet/AspNetCore.git", + "Repository": "https://github.com/dotnet/aspnetcore.git", "BranchOrCommit": "master", "Project": "src/Routing/benchmarkapps/Benchmarks/Benchmarks.csproj" }, diff --git a/src/Http/WebUtilities/ref/Microsoft.AspNetCore.WebUtilities.netcoreapp.cs b/src/Http/WebUtilities/ref/Microsoft.AspNetCore.WebUtilities.netcoreapp.cs index c27af66ed3..eb8e7539c1 100644 --- a/src/Http/WebUtilities/ref/Microsoft.AspNetCore.WebUtilities.netcoreapp.cs +++ b/src/Http/WebUtilities/ref/Microsoft.AspNetCore.WebUtilities.netcoreapp.cs @@ -92,26 +92,26 @@ namespace Microsoft.AspNetCore.WebUtilities { public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { } public FileMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section, Microsoft.Net.Http.Headers.ContentDispositionHeaderValue header) { } - public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.IO.Stream FileStream { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class FormMultipartSection { public FormMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section) { } public FormMultipartSection(Microsoft.AspNetCore.WebUtilities.MultipartSection section, Microsoft.Net.Http.Headers.ContentDispositionHeaderValue header) { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.WebUtilities.MultipartSection Section { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Threading.Tasks.Task GetValueAsync() { throw null; } } public partial class FormPipeReader { public FormPipeReader(System.IO.Pipelines.PipeReader pipeReader) { } public FormPipeReader(System.IO.Pipelines.PipeReader pipeReader, System.Text.Encoding encoding) { } - public int KeyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ValueCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ValueLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int KeyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ValueCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ValueLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task> ReadFormAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } @@ -125,9 +125,9 @@ namespace Microsoft.AspNetCore.WebUtilities public FormReader(System.IO.Stream stream, System.Text.Encoding encoding, System.Buffers.ArrayPool charPool) { } public FormReader(string data) { } public FormReader(string data, System.Buffers.ArrayPool charPool) { } - public int KeyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ValueCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ValueLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int KeyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ValueCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ValueLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Dispose() { } public System.Collections.Generic.Dictionary ReadForm() { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.WebUtilities public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding encoding) { } public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding encoding, int bufferSize) { } public HttpResponseStreamWriter(System.IO.Stream stream, System.Text.Encoding encoding, int bufferSize, System.Buffers.ArrayPool bytePool, System.Buffers.ArrayPool charPool) { } - public override System.Text.Encoding Encoding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public override System.Text.Encoding Encoding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override void Dispose(bool disposing) { } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } @@ -173,7 +173,7 @@ namespace Microsoft.AspNetCore.WebUtilities private int _dummyPrimitive; public bool HasValues { get { throw null; } } public int KeyCount { get { throw null; } } - public int ValueCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int ValueCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Append(string key, string value) { } public System.Collections.Generic.Dictionary GetResults() { throw null; } } @@ -183,20 +183,20 @@ namespace Microsoft.AspNetCore.WebUtilities public const int DefaultHeadersLengthLimit = 16384; public MultipartReader(string boundary, System.IO.Stream stream) { } public MultipartReader(string boundary, System.IO.Stream stream, int bufferSize) { } - public long? BodyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int HeadersCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int HeadersLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public long? BodyLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int HeadersCountLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int HeadersLengthLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task ReadNextSectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } public partial class MultipartSection { public MultipartSection() { } - public long? BaseStreamOffset { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public long? BaseStreamOffset { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string ContentDisposition { get { throw null; } } public string ContentType { get { throw null; } } - public System.Collections.Generic.Dictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.Dictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class MultipartSectionConverterExtensions { diff --git a/src/Http/WebUtilities/src/FileBufferingWriteStream.cs b/src/Http/WebUtilities/src/FileBufferingWriteStream.cs index fd9c993bad..354829c3b8 100644 --- a/src/Http/WebUtilities/src/FileBufferingWriteStream.cs +++ b/src/Http/WebUtilities/src/FileBufferingWriteStream.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.WebUtilities /// Defaults to 32kb. /// /// - /// The maximum amouont of bytes that the is allowed to buffer. + /// The maximum amount of bytes that the is allowed to buffer. /// /// Provides the location of the directory to write buffered contents to. /// When unspecified, uses the value specified by the environment variable ASPNETCORE_TEMP if available, otherwise @@ -117,7 +117,7 @@ namespace Microsoft.AspNetCore.WebUtilities } else { - // If the MemoryStream is incapable of accomodating the content to be written + // If the MemoryStream is incapable of accommodating the content to be written // spool to disk. EnsureFileStream(); @@ -238,7 +238,7 @@ namespace Microsoft.AspNetCore.WebUtilities { if (Disposed) { - throw new ObjectDisposedException(nameof(FileBufferingReadStream)); + throw new ObjectDisposedException(nameof(FileBufferingWriteStream)); } } diff --git a/src/Http/WebUtilities/src/FormPipeReader.cs b/src/Http/WebUtilities/src/FormPipeReader.cs index 60f337757b..e6372c29e4 100644 --- a/src/Http/WebUtilities/src/FormPipeReader.cs +++ b/src/Http/WebUtilities/src/FormPipeReader.cs @@ -29,6 +29,7 @@ namespace Microsoft.AspNetCore.WebUtilities private const int DefaultValueLengthLimit = 1024 * 1024 * 4; // Used for UTF8/ASCII (precalculated for fast path) + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static private static ReadOnlySpan UTF8EqualEncoded => new byte[] { (byte)'=' }; private static ReadOnlySpan UTF8AndEncoded => new byte[] { (byte)'&' }; diff --git a/src/Http/WebUtilities/src/QueryHelpers.cs b/src/Http/WebUtilities/src/QueryHelpers.cs index c1c23b64e9..a3b13b033c 100644 --- a/src/Http/WebUtilities/src/QueryHelpers.cs +++ b/src/Http/WebUtilities/src/QueryHelpers.cs @@ -9,6 +9,9 @@ using Microsoft.Extensions.Primitives; namespace Microsoft.AspNetCore.WebUtilities { + /// + /// Provides methods for parsing and manipulating query strings. + /// public static class QueryHelpers { /// @@ -18,6 +21,9 @@ namespace Microsoft.AspNetCore.WebUtilities /// The name of the query key. /// The query value. /// The combined result. + /// is null. + /// is null. + /// is null. public static string AddQueryString(string uri, string name, string value) { if (uri == null) @@ -45,6 +51,8 @@ namespace Microsoft.AspNetCore.WebUtilities /// The base uri. /// A collection of name value query pairs to append. /// The combined result. + /// is null. + /// is null. public static string AddQueryString(string uri, IDictionary queryString) { if (uri == null) @@ -91,6 +99,11 @@ namespace Microsoft.AspNetCore.WebUtilities sb.Append(uriToBeAppended); foreach (var parameter in queryString) { + if (parameter.Value == null) + { + continue; + } + sb.Append(hasQuery ? '&' : '?'); sb.Append(UrlEncoder.Default.Encode(parameter.Key)); sb.Append('='); @@ -119,7 +132,6 @@ namespace Microsoft.AspNetCore.WebUtilities return result; } - /// /// Parse a query string into its component key and value parts. /// @@ -188,4 +200,4 @@ namespace Microsoft.AspNetCore.WebUtilities return accumulator.GetResults(); } } -} \ No newline at end of file +} diff --git a/src/Http/WebUtilities/test/QueryHelpersTests.cs b/src/Http/WebUtilities/test/QueryHelpersTests.cs index 5607ab87aa..a64bcbf03b 100644 --- a/src/Http/WebUtilities/test/QueryHelpersTests.cs +++ b/src/Http/WebUtilities/test/QueryHelpersTests.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Linq; using Xunit; @@ -53,6 +54,12 @@ namespace Microsoft.AspNetCore.WebUtilities Assert.Equal(new[] { "value1", "" }, collection[""]); } + [Fact] + public void AddQueryStringWithNullValueThrows() + { + Assert.Throws("value" ,() => QueryHelpers.AddQueryString("http://contoso.com/", "hello", null)); + } + [Theory] [InlineData("http://contoso.com/", "http://contoso.com/?hello=world")] [InlineData("http://contoso.com/someaction", "http://contoso.com/someaction?hello=world")] @@ -81,34 +88,36 @@ namespace Microsoft.AspNetCore.WebUtilities } [Theory] - [InlineData("http://contoso.com/", "http://contoso.com/?hello=world&some=text")] - [InlineData("http://contoso.com/someaction", "http://contoso.com/someaction?hello=world&some=text")] - [InlineData("http://contoso.com/someaction?q=1", "http://contoso.com/someaction?q=1&hello=world&some=text")] - [InlineData("http://contoso.com/some#action", "http://contoso.com/some?hello=world&some=text#action")] - [InlineData("http://contoso.com/some?q=1#action", "http://contoso.com/some?q=1&hello=world&some=text#action")] - [InlineData("http://contoso.com/#action", "http://contoso.com/?hello=world&some=text#action")] + [InlineData("http://contoso.com/", "http://contoso.com/?hello=world&some=text&another=")] + [InlineData("http://contoso.com/someaction", "http://contoso.com/someaction?hello=world&some=text&another=")] + [InlineData("http://contoso.com/someaction?q=1", "http://contoso.com/someaction?q=1&hello=world&some=text&another=")] + [InlineData("http://contoso.com/some#action", "http://contoso.com/some?hello=world&some=text&another=#action")] + [InlineData("http://contoso.com/some?q=1#action", "http://contoso.com/some?q=1&hello=world&some=text&another=#action")] + [InlineData("http://contoso.com/#action", "http://contoso.com/?hello=world&some=text&another=#action")] [InlineData( "http://contoso.com/someaction?q=test#anchor?value", - "http://contoso.com/someaction?q=test&hello=world&some=text#anchor?value")] + "http://contoso.com/someaction?q=test&hello=world&some=text&another=#anchor?value")] [InlineData( "http://contoso.com/someaction#anchor?stuff", - "http://contoso.com/someaction?hello=world&some=text#anchor?stuff")] + "http://contoso.com/someaction?hello=world&some=text&another=#anchor?stuff")] [InlineData( "http://contoso.com/someaction?name?something", - "http://contoso.com/someaction?name?something&hello=world&some=text")] + "http://contoso.com/someaction?name?something&hello=world&some=text&another=")] [InlineData( "http://contoso.com/someaction#name#something", - "http://contoso.com/someaction?hello=world&some=text#name#something")] + "http://contoso.com/someaction?hello=world&some=text&another=#name#something")] public void AddQueryStringWithDictionary(string uri, string expectedUri) { var queryStrings = new Dictionary() { { "hello", "world" }, - { "some", "text" } + { "some", "text" }, + { "another", string.Empty }, + { "invisible", null } }; var result = QueryHelpers.AddQueryString(uri, queryStrings); Assert.Equal(expectedUri, result); } } -} \ No newline at end of file +} diff --git a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs index a72e128237..099fdf73e5 100644 --- a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs +++ b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/ConfigureSigningCredentialsTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer X509KeyStorageFlags.DefaultKeySet); [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] [FrameworkSkipCondition(RuntimeFrameworks.CLR)] public void Configure_AddsDevelopmentKeyFromConfiguration() { @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public void Configure_LoadsPfxCertificateCredentialFromConfiguration() { // Arrange @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public void Configure_LoadsCertificateStoreCertificateCredentialFromConfiguration() { try diff --git a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs index ced72bd9cc..c5d543dfe9 100644 --- a/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs +++ b/src/Identity/ApiAuthorization.IdentityServer/test/Configuration/SigningKeysLoaderTests.cs @@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer.Configuration } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public static void LoadFromStoreCert_SkipsCertificatesNotYetValid() { try @@ -82,7 +82,7 @@ namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer.Configuration } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public static void LoadFromStoreCert_PrefersCertificatesCloserToExpirationDate() { try @@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.ApiAuthorization.IdentityServer.Configuration } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6720")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")] public static void LoadFromStoreCert_SkipsExpiredCertificates() { try diff --git a/src/Identity/Core/ref/Microsoft.AspNetCore.Identity.netcoreapp.cs b/src/Identity/Core/ref/Microsoft.AspNetCore.Identity.netcoreapp.cs index a57c5891f1..0ccafd325b 100644 --- a/src/Identity/Core/ref/Microsoft.AspNetCore.Identity.netcoreapp.cs +++ b/src/Identity/Core/ref/Microsoft.AspNetCore.Identity.netcoreapp.cs @@ -16,16 +16,16 @@ namespace Microsoft.AspNetCore.Identity public partial class DataProtectionTokenProviderOptions { public DataProtectionTokenProviderOptions() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan TokenLifespan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan TokenLifespan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DataProtectorTokenProvider : Microsoft.AspNetCore.Identity.IUserTwoFactorTokenProvider where TUser : class { public DataProtectorTokenProvider(Microsoft.AspNetCore.DataProtection.IDataProtectionProvider dataProtectionProvider, Microsoft.Extensions.Options.IOptions options, Microsoft.Extensions.Logging.ILogger> logger) { } - public Microsoft.Extensions.Logging.ILogger> Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Logging.ILogger> Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string Name { get { throw null; } } - protected Microsoft.AspNetCore.Identity.DataProtectionTokenProviderOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.DataProtection.IDataProtector Protector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Identity.DataProtectionTokenProviderOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.DataProtection.IDataProtector Protector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Threading.Tasks.Task CanGenerateTwoFactorTokenAsync(Microsoft.AspNetCore.Identity.UserManager manager, TUser user) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task GenerateAsync(string purpose, Microsoft.AspNetCore.Identity.UserManager manager, TUser user) { throw null; } @@ -35,9 +35,9 @@ namespace Microsoft.AspNetCore.Identity public partial class ExternalLoginInfo : Microsoft.AspNetCore.Identity.UserLoginInfo { public ExternalLoginInfo(System.Security.Claims.ClaimsPrincipal principal, string loginProvider, string providerKey, string displayName) : base (default(string), default(string), default(string)) { } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties AuthenticationProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IEnumerable AuthenticationTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties AuthenticationProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IEnumerable AuthenticationTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class IdentityBuilderExtensions { @@ -65,10 +65,10 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityCookiesBuilder { public IdentityCookiesBuilder() { } - public Microsoft.Extensions.Options.OptionsBuilder ApplicationCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Extensions.Options.OptionsBuilder ExternalCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Extensions.Options.OptionsBuilder TwoFactorRememberMeCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Extensions.Options.OptionsBuilder TwoFactorUserIdCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.Options.OptionsBuilder ApplicationCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Extensions.Options.OptionsBuilder ExternalCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Extensions.Options.OptionsBuilder TwoFactorRememberMeCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Extensions.Options.OptionsBuilder TwoFactorUserIdCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface ISecurityStampValidator { @@ -80,8 +80,8 @@ namespace Microsoft.AspNetCore.Identity public partial class SecurityStampRefreshingPrincipalContext { public SecurityStampRefreshingPrincipalContext() { } - public System.Security.Claims.ClaimsPrincipal CurrentPrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Claims.ClaimsPrincipal NewPrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Claims.ClaimsPrincipal CurrentPrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Claims.ClaimsPrincipal NewPrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class SecurityStampValidator { @@ -91,16 +91,16 @@ namespace Microsoft.AspNetCore.Identity public partial class SecurityStampValidatorOptions { public SecurityStampValidatorOptions() { } - public System.Func OnRefreshingPrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan ValidationInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func OnRefreshingPrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan ValidationInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SecurityStampValidator : Microsoft.AspNetCore.Identity.ISecurityStampValidator where TUser : class { public SecurityStampValidator(Microsoft.Extensions.Options.IOptions options, Microsoft.AspNetCore.Identity.SignInManager signInManager, Microsoft.AspNetCore.Authentication.ISystemClock clock, Microsoft.Extensions.Logging.ILoggerFactory logger) { } - public Microsoft.AspNetCore.Authentication.ISystemClock Clock { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Identity.SignInManager SignInManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.ISystemClock Clock { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.SecurityStampValidatorOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Identity.SignInManager SignInManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] protected virtual System.Threading.Tasks.Task SecurityStampVerified(TUser user, Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext context) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -110,11 +110,11 @@ namespace Microsoft.AspNetCore.Identity public partial class SignInManager where TUser : class { public SignInManager(Microsoft.AspNetCore.Identity.UserManager userManager, Microsoft.AspNetCore.Http.IHttpContextAccessor contextAccessor, Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory claimsFactory, Microsoft.Extensions.Options.IOptions optionsAccessor, Microsoft.Extensions.Logging.ILogger> logger, Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider schemes, Microsoft.AspNetCore.Identity.IUserConfirmation confirmation) { } - public Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory ClaimsFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory ClaimsFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.HttpContext Context { get { throw null; } set { } } - public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.UserManager UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.UserManager UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task CanSignInAsync(TUser user) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] diff --git a/src/Identity/Core/src/IdentityBuilderExtensions.cs b/src/Identity/Core/src/IdentityBuilderExtensions.cs index df0a1c59d0..2d77c5c3f8 100644 --- a/src/Identity/Core/src/IdentityBuilderExtensions.cs +++ b/src/Identity/Core/src/IdentityBuilderExtensions.cs @@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds a for the . + /// Adds a for the . /// /// The current instance. /// The current instance. @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds a for the . + /// Adds a for the . /// /// The type of the sign in manager to add. /// The current instance. diff --git a/src/Identity/Core/src/SignInManager.cs b/src/Identity/Core/src/SignInManager.cs index 8cae14795a..e54c0f6155 100644 --- a/src/Identity/Core/src/SignInManager.cs +++ b/src/Identity/Core/src/SignInManager.cs @@ -161,10 +161,10 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Regenerates the user's application cookie, whilst preserving the existing - /// AuthenticationProperties like rememberMe, as an asynchronous operation. + /// Signs in the specified , whilst preserving the existing + /// AuthenticationProperties of the current signed-in user like rememberMe, as an asynchronous operation. /// - /// The user whose sign-in cookie should be refreshed. + /// The user to sign-in. /// The task object representing the asynchronous operation. public virtual async Task RefreshSignInAsync(TUser user) { diff --git a/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netcoreapp.cs b/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netcoreapp.cs index 17b2093144..6ce362ca04 100644 --- a/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netcoreapp.cs +++ b/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netcoreapp.cs @@ -22,9 +22,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { protected IdentityDbContext() { } public IdentityDbContext(Microsoft.EntityFrameworkCore.DbContextOptions options) { } - public virtual Microsoft.EntityFrameworkCore.DbSet RoleClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet UserRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet RoleClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder builder) { } } public partial class IdentityUserContext : Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserContext where TUser : Microsoft.AspNetCore.Identity.IdentityUser @@ -41,10 +41,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { protected IdentityUserContext() { } public IdentityUserContext(Microsoft.EntityFrameworkCore.DbContextOptions options) { } - public virtual Microsoft.EntityFrameworkCore.DbSet UserClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet UserLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet Users { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet UserTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet Users { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder builder) { } } public partial class RoleStore : Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore where TRole : Microsoft.AspNetCore.Identity.IdentityRole @@ -62,9 +62,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore public partial class RoleStore : Microsoft.AspNetCore.Identity.IQueryableRoleStore, Microsoft.AspNetCore.Identity.IRoleClaimStore, Microsoft.AspNetCore.Identity.IRoleStore, System.IDisposable where TRole : Microsoft.AspNetCore.Identity.IdentityRole where TContext : Microsoft.EntityFrameworkCore.DbContext where TKey : System.IEquatable where TUserRole : Microsoft.AspNetCore.Identity.IdentityUserRole, new() where TRoleClaim : Microsoft.AspNetCore.Identity.IdentityRoleClaim, new() { public RoleStore(TContext context, Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer = null) { } - public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Linq.IQueryable Roles { get { throw null; } } public virtual System.Threading.Tasks.Task AddClaimAsync(TRole role, System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual TKey ConvertIdFromString(string id) { throw null; } @@ -105,8 +105,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore public partial class UserOnlyStore : Microsoft.AspNetCore.Identity.UserStoreBase, Microsoft.AspNetCore.Identity.IProtectedUserStore, Microsoft.AspNetCore.Identity.IQueryableUserStore, Microsoft.AspNetCore.Identity.IUserAuthenticationTokenStore, Microsoft.AspNetCore.Identity.IUserAuthenticatorKeyStore, Microsoft.AspNetCore.Identity.IUserClaimStore, Microsoft.AspNetCore.Identity.IUserEmailStore, Microsoft.AspNetCore.Identity.IUserLockoutStore, Microsoft.AspNetCore.Identity.IUserLoginStore, Microsoft.AspNetCore.Identity.IUserPasswordStore, Microsoft.AspNetCore.Identity.IUserPhoneNumberStore, Microsoft.AspNetCore.Identity.IUserSecurityStampStore, Microsoft.AspNetCore.Identity.IUserStore, Microsoft.AspNetCore.Identity.IUserTwoFactorRecoveryCodeStore, Microsoft.AspNetCore.Identity.IUserTwoFactorStore, System.IDisposable where TUser : Microsoft.AspNetCore.Identity.IdentityUser where TContext : Microsoft.EntityFrameworkCore.DbContext where TKey : System.IEquatable where TUserClaim : Microsoft.AspNetCore.Identity.IdentityUserClaim, new() where TUserLogin : Microsoft.AspNetCore.Identity.IdentityUserLogin, new() where TUserToken : Microsoft.AspNetCore.Identity.IdentityUserToken, new() { public UserOnlyStore(TContext context, Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer = null) : base (default(Microsoft.AspNetCore.Identity.IdentityErrorDescriber)) { } - public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.EntityFrameworkCore.DbSet UserClaims { get { throw null; } } protected Microsoft.EntityFrameworkCore.DbSet UserLogins { get { throw null; } } public override System.Linq.IQueryable Users { get { throw null; } } @@ -164,8 +164,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore public partial class UserStore : Microsoft.AspNetCore.Identity.UserStoreBase, Microsoft.AspNetCore.Identity.IProtectedUserStore, Microsoft.AspNetCore.Identity.IUserStore, System.IDisposable where TUser : Microsoft.AspNetCore.Identity.IdentityUser where TRole : Microsoft.AspNetCore.Identity.IdentityRole where TContext : Microsoft.EntityFrameworkCore.DbContext where TKey : System.IEquatable where TUserClaim : Microsoft.AspNetCore.Identity.IdentityUserClaim, new() where TUserRole : Microsoft.AspNetCore.Identity.IdentityUserRole, new() where TUserLogin : Microsoft.AspNetCore.Identity.IdentityUserLogin, new() where TUserToken : Microsoft.AspNetCore.Identity.IdentityUserToken, new() where TRoleClaim : Microsoft.AspNetCore.Identity.IdentityRoleClaim, new() { public UserStore(TContext context, Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer = null) : base (default(Microsoft.AspNetCore.Identity.IdentityErrorDescriber)) { } - public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override System.Linq.IQueryable Users { get { throw null; } } public override System.Threading.Tasks.Task AddClaimsAsync(TUser user, System.Collections.Generic.IEnumerable claims, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.Task AddLoginAsync(TUser user, Microsoft.AspNetCore.Identity.UserLoginInfo login, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } diff --git a/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netstandard2.1.cs b/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netstandard2.1.cs index 17b2093144..6ce362ca04 100644 --- a/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netstandard2.1.cs +++ b/src/Identity/EntityFrameworkCore/ref/Microsoft.AspNetCore.Identity.EntityFrameworkCore.netstandard2.1.cs @@ -22,9 +22,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { protected IdentityDbContext() { } public IdentityDbContext(Microsoft.EntityFrameworkCore.DbContextOptions options) { } - public virtual Microsoft.EntityFrameworkCore.DbSet RoleClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet UserRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet RoleClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder builder) { } } public partial class IdentityUserContext : Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserContext where TUser : Microsoft.AspNetCore.Identity.IdentityUser @@ -41,10 +41,10 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore { protected IdentityUserContext() { } public IdentityUserContext(Microsoft.EntityFrameworkCore.DbContextOptions options) { } - public virtual Microsoft.EntityFrameworkCore.DbSet UserClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet UserLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet Users { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.EntityFrameworkCore.DbSet UserTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserClaims { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet Users { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.EntityFrameworkCore.DbSet UserTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override void OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder builder) { } } public partial class RoleStore : Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore where TRole : Microsoft.AspNetCore.Identity.IdentityRole @@ -62,9 +62,9 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore public partial class RoleStore : Microsoft.AspNetCore.Identity.IQueryableRoleStore, Microsoft.AspNetCore.Identity.IRoleClaimStore, Microsoft.AspNetCore.Identity.IRoleStore, System.IDisposable where TRole : Microsoft.AspNetCore.Identity.IdentityRole where TContext : Microsoft.EntityFrameworkCore.DbContext where TKey : System.IEquatable where TUserRole : Microsoft.AspNetCore.Identity.IdentityUserRole, new() where TRoleClaim : Microsoft.AspNetCore.Identity.IdentityRoleClaim, new() { public RoleStore(TContext context, Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer = null) { } - public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Linq.IQueryable Roles { get { throw null; } } public virtual System.Threading.Tasks.Task AddClaimAsync(TRole role, System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual TKey ConvertIdFromString(string id) { throw null; } @@ -105,8 +105,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore public partial class UserOnlyStore : Microsoft.AspNetCore.Identity.UserStoreBase, Microsoft.AspNetCore.Identity.IProtectedUserStore, Microsoft.AspNetCore.Identity.IQueryableUserStore, Microsoft.AspNetCore.Identity.IUserAuthenticationTokenStore, Microsoft.AspNetCore.Identity.IUserAuthenticatorKeyStore, Microsoft.AspNetCore.Identity.IUserClaimStore, Microsoft.AspNetCore.Identity.IUserEmailStore, Microsoft.AspNetCore.Identity.IUserLockoutStore, Microsoft.AspNetCore.Identity.IUserLoginStore, Microsoft.AspNetCore.Identity.IUserPasswordStore, Microsoft.AspNetCore.Identity.IUserPhoneNumberStore, Microsoft.AspNetCore.Identity.IUserSecurityStampStore, Microsoft.AspNetCore.Identity.IUserStore, Microsoft.AspNetCore.Identity.IUserTwoFactorRecoveryCodeStore, Microsoft.AspNetCore.Identity.IUserTwoFactorStore, System.IDisposable where TUser : Microsoft.AspNetCore.Identity.IdentityUser where TContext : Microsoft.EntityFrameworkCore.DbContext where TKey : System.IEquatable where TUserClaim : Microsoft.AspNetCore.Identity.IdentityUserClaim, new() where TUserLogin : Microsoft.AspNetCore.Identity.IdentityUserLogin, new() where TUserToken : Microsoft.AspNetCore.Identity.IdentityUserToken, new() { public UserOnlyStore(TContext context, Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer = null) : base (default(Microsoft.AspNetCore.Identity.IdentityErrorDescriber)) { } - public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.EntityFrameworkCore.DbSet UserClaims { get { throw null; } } protected Microsoft.EntityFrameworkCore.DbSet UserLogins { get { throw null; } } public override System.Linq.IQueryable Users { get { throw null; } } @@ -164,8 +164,8 @@ namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore public partial class UserStore : Microsoft.AspNetCore.Identity.UserStoreBase, Microsoft.AspNetCore.Identity.IProtectedUserStore, Microsoft.AspNetCore.Identity.IUserStore, System.IDisposable where TUser : Microsoft.AspNetCore.Identity.IdentityUser where TRole : Microsoft.AspNetCore.Identity.IdentityRole where TContext : Microsoft.EntityFrameworkCore.DbContext where TKey : System.IEquatable where TUserClaim : Microsoft.AspNetCore.Identity.IdentityUserClaim, new() where TUserRole : Microsoft.AspNetCore.Identity.IdentityUserRole, new() where TUserLogin : Microsoft.AspNetCore.Identity.IdentityUserLogin, new() where TUserToken : Microsoft.AspNetCore.Identity.IdentityUserToken, new() where TRoleClaim : Microsoft.AspNetCore.Identity.IdentityRoleClaim, new() { public UserStore(TContext context, Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer = null) : base (default(Microsoft.AspNetCore.Identity.IdentityErrorDescriber)) { } - public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AutoSaveChanges { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override System.Linq.IQueryable Users { get { throw null; } } public override System.Threading.Tasks.Task AddClaimsAsync(TUser user, System.Collections.Generic.IEnumerable claims, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override System.Threading.Tasks.Task AddLoginAsync(TUser user, Microsoft.AspNetCore.Identity.UserLoginInfo login, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } diff --git a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs index f934eb8db2..bbef8ce4cc 100644 --- a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs +++ b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netcoreapp.cs @@ -15,10 +15,10 @@ namespace Microsoft.AspNetCore.Identity public partial class ClaimsIdentityOptions { public ClaimsIdentityOptions() { } - public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UserNameClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UserNameClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DefaultPersonalDataProtector : Microsoft.AspNetCore.Identity.IPersonalDataProtector { @@ -44,9 +44,9 @@ namespace Microsoft.AspNetCore.Identity { public IdentityBuilder(System.Type user, Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } public IdentityBuilder(System.Type user, System.Type role, Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } - public System.Type RoleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type UserType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type RoleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type UserType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddClaimsPrincipalFactory() where TFactory : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddErrorDescriber() where TDescriber : Microsoft.AspNetCore.Identity.IdentityErrorDescriber { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddPasswordValidator() where TValidator : class { throw null; } @@ -57,6 +57,7 @@ namespace Microsoft.AspNetCore.Identity public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddRoleValidator() where TRole : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddTokenProvider(string providerName, System.Type provider) { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddTokenProvider(string providerName) where TProvider : class { throw null; } + public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserConfirmation() where TUserConfirmation : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserManager() where TUserManager : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserStore() where TStore : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserValidator() where TValidator : class { throw null; } @@ -64,8 +65,8 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityError { public IdentityError() { } - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityErrorDescriber { @@ -96,19 +97,19 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityOptions { public IdentityOptions() { } - public Microsoft.AspNetCore.Identity.ClaimsIdentityOptions ClaimsIdentity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.LockoutOptions Lockout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.PasswordOptions Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.SignInOptions SignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.StoreOptions Stores { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.TokenOptions Tokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.UserOptions User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.ClaimsIdentityOptions ClaimsIdentity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.LockoutOptions Lockout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.PasswordOptions Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.SignInOptions SignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.StoreOptions Stores { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.TokenOptions Tokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.UserOptions User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityResult { public IdentityResult() { } public System.Collections.Generic.IEnumerable Errors { get { throw null; } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Identity.IdentityResult Success { get { throw null; } } public static Microsoft.AspNetCore.Identity.IdentityResult Failed(params Microsoft.AspNetCore.Identity.IdentityError[] errors) { throw null; } public override string ToString() { throw null; } @@ -294,9 +295,9 @@ namespace Microsoft.AspNetCore.Identity public partial class LockoutOptions { public LockoutOptions() { } - public bool AllowedForNewUsers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan DefaultLockoutTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MaxFailedAccessAttempts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowedForNewUsers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan DefaultLockoutTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MaxFailedAccessAttempts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public enum PasswordHasherCompatibilityMode { @@ -306,8 +307,8 @@ namespace Microsoft.AspNetCore.Identity public partial class PasswordHasherOptions { public PasswordHasherOptions() { } - public Microsoft.AspNetCore.Identity.PasswordHasherCompatibilityMode CompatibilityMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int IterationCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.PasswordHasherCompatibilityMode CompatibilityMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int IterationCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PasswordHasher : Microsoft.AspNetCore.Identity.IPasswordHasher where TUser : class { @@ -318,17 +319,17 @@ namespace Microsoft.AspNetCore.Identity public partial class PasswordOptions { public PasswordOptions() { } - public bool RequireDigit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RequiredLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RequiredUniqueChars { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireLowercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireNonAlphanumeric { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireUppercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RequireDigit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RequiredLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RequiredUniqueChars { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireLowercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireNonAlphanumeric { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireUppercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PasswordValidator : Microsoft.AspNetCore.Identity.IPasswordValidator where TUser : class { public PasswordValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool IsDigit(char c) { throw null; } public virtual bool IsLetterOrDigit(char c) { throw null; } public virtual bool IsLower(char c) { throw null; } @@ -361,12 +362,12 @@ namespace Microsoft.AspNetCore.Identity { public RoleManager(Microsoft.AspNetCore.Identity.IRoleStore store, System.Collections.Generic.IEnumerable> roleValidators, Microsoft.AspNetCore.Identity.ILookupNormalizer keyNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors, Microsoft.Extensions.Logging.ILogger> logger) { } protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Linq.IQueryable Roles { get { throw null; } } - public System.Collections.Generic.IList> RoleValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Identity.IRoleStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList> RoleValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Identity.IRoleStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool SupportsQueryableRoles { get { throw null; } } public virtual bool SupportsRoleClaims { get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -406,20 +407,20 @@ namespace Microsoft.AspNetCore.Identity public partial class SignInOptions { public SignInOptions() { } - public bool RequireConfirmedAccount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireConfirmedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireConfirmedPhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RequireConfirmedAccount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireConfirmedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireConfirmedPhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SignInResult { public SignInResult() { } public static Microsoft.AspNetCore.Identity.SignInResult Failed { get { throw null; } } - public bool IsLockedOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public bool IsNotAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public bool IsLockedOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public bool IsNotAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Identity.SignInResult LockedOut { get { throw null; } } public static Microsoft.AspNetCore.Identity.SignInResult NotAllowed { get { throw null; } } - public bool RequiresTwoFactor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public bool RequiresTwoFactor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Identity.SignInResult Success { get { throw null; } } public static Microsoft.AspNetCore.Identity.SignInResult TwoFactorRequired { get { throw null; } } public override string ToString() { throw null; } @@ -427,8 +428,8 @@ namespace Microsoft.AspNetCore.Identity public partial class StoreOptions { public StoreOptions() { } - public int MaxLengthForKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ProtectPersonalData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int MaxLengthForKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ProtectPersonalData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenOptions { @@ -437,19 +438,19 @@ namespace Microsoft.AspNetCore.Identity public static readonly string DefaultPhoneProvider; public static readonly string DefaultProvider; public TokenOptions() { } - public string AuthenticatorIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string AuthenticatorTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ChangeEmailTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ChangePhoneNumberTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EmailConfirmationTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PasswordResetTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.Dictionary ProviderMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticatorIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string AuthenticatorTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ChangeEmailTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ChangePhoneNumberTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EmailConfirmationTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PasswordResetTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.Dictionary ProviderMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenProviderDescriptor { public TokenProviderDescriptor(System.Type type) { } - public object ProviderInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ProviderType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object ProviderInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ProviderType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class TotpSecurityStampBasedTokenProvider : Microsoft.AspNetCore.Identity.IUserTwoFactorTokenProvider where TUser : class { @@ -471,8 +472,8 @@ namespace Microsoft.AspNetCore.Identity public partial class UserClaimsPrincipalFactory : Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory where TUser : class { public UserClaimsPrincipalFactory(Microsoft.AspNetCore.Identity.UserManager userManager, Microsoft.Extensions.Options.IOptions optionsAccessor) { } - public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Identity.UserManager UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Identity.UserManager UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task CreateAsync(TUser user) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -481,16 +482,16 @@ namespace Microsoft.AspNetCore.Identity public partial class UserClaimsPrincipalFactory : Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory where TUser : class where TRole : class { public UserClaimsPrincipalFactory(Microsoft.AspNetCore.Identity.UserManager userManager, Microsoft.AspNetCore.Identity.RoleManager roleManager, Microsoft.Extensions.Options.IOptions options) : base (default(Microsoft.AspNetCore.Identity.UserManager), default(Microsoft.Extensions.Options.IOptions)) { } - public Microsoft.AspNetCore.Identity.RoleManager RoleManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.RoleManager RoleManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] protected override System.Threading.Tasks.Task GenerateClaimsAsync(TUser user) { throw null; } } public partial class UserLoginInfo { public UserLoginInfo(string loginProvider, string providerKey, string displayName) { } - public string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UserManager : System.IDisposable where TUser : class { @@ -499,13 +500,13 @@ namespace Microsoft.AspNetCore.Identity public const string ResetPasswordTokenPurpose = "ResetPassword"; public UserManager(Microsoft.AspNetCore.Identity.IUserStore store, Microsoft.Extensions.Options.IOptions optionsAccessor, Microsoft.AspNetCore.Identity.IPasswordHasher passwordHasher, System.Collections.Generic.IEnumerable> userValidators, System.Collections.Generic.IEnumerable> passwordValidators, Microsoft.AspNetCore.Identity.ILookupNormalizer keyNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors, System.IServiceProvider services, Microsoft.Extensions.Logging.ILogger> logger) { } protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.IPasswordHasher PasswordHasher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList> PasswordValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected internal Microsoft.AspNetCore.Identity.IUserStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.IPasswordHasher PasswordHasher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList> PasswordValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected internal Microsoft.AspNetCore.Identity.IUserStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual bool SupportsQueryableUsers { get { throw null; } } public virtual bool SupportsUserAuthenticationTokens { get { throw null; } } public virtual bool SupportsUserAuthenticatorKey { get { throw null; } } @@ -520,7 +521,7 @@ namespace Microsoft.AspNetCore.Identity public virtual bool SupportsUserTwoFactor { get { throw null; } } public virtual bool SupportsUserTwoFactorRecoveryCodes { get { throw null; } } public virtual System.Linq.IQueryable Users { get { throw null; } } - public System.Collections.Generic.IList> UserValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList> UserValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task AccessFailedAsync(TUser user) { throw null; } public virtual System.Threading.Tasks.Task AddClaimAsync(TUser user, System.Security.Claims.Claim claim) { throw null; } @@ -679,13 +680,13 @@ namespace Microsoft.AspNetCore.Identity public partial class UserOptions { public UserOptions() { } - public string AllowedUserNameCharacters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireUniqueEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AllowedUserNameCharacters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireUniqueEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UserValidator : Microsoft.AspNetCore.Identity.IUserValidator where TUser : class { public UserValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task ValidateAsync(Microsoft.AspNetCore.Identity.UserManager manager, TUser user) { throw null; } } diff --git a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs index f934eb8db2..bbef8ce4cc 100644 --- a/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs +++ b/src/Identity/Extensions.Core/ref/Microsoft.Extensions.Identity.Core.netstandard2.0.cs @@ -15,10 +15,10 @@ namespace Microsoft.AspNetCore.Identity public partial class ClaimsIdentityOptions { public ClaimsIdentityOptions() { } - public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UserNameClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RoleClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SecurityStampClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UserIdClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UserNameClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DefaultPersonalDataProtector : Microsoft.AspNetCore.Identity.IPersonalDataProtector { @@ -44,9 +44,9 @@ namespace Microsoft.AspNetCore.Identity { public IdentityBuilder(System.Type user, Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } public IdentityBuilder(System.Type user, System.Type role, Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } - public System.Type RoleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type UserType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type RoleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type UserType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddClaimsPrincipalFactory() where TFactory : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddErrorDescriber() where TDescriber : Microsoft.AspNetCore.Identity.IdentityErrorDescriber { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddPasswordValidator() where TValidator : class { throw null; } @@ -57,6 +57,7 @@ namespace Microsoft.AspNetCore.Identity public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddRoleValidator() where TRole : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddTokenProvider(string providerName, System.Type provider) { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddTokenProvider(string providerName) where TProvider : class { throw null; } + public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserConfirmation() where TUserConfirmation : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserManager() where TUserManager : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserStore() where TStore : class { throw null; } public virtual Microsoft.AspNetCore.Identity.IdentityBuilder AddUserValidator() where TValidator : class { throw null; } @@ -64,8 +65,8 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityError { public IdentityError() { } - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityErrorDescriber { @@ -96,19 +97,19 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityOptions { public IdentityOptions() { } - public Microsoft.AspNetCore.Identity.ClaimsIdentityOptions ClaimsIdentity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.LockoutOptions Lockout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.PasswordOptions Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.SignInOptions SignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.StoreOptions Stores { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.TokenOptions Tokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.UserOptions User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.ClaimsIdentityOptions ClaimsIdentity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.LockoutOptions Lockout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.PasswordOptions Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.SignInOptions SignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.StoreOptions Stores { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.TokenOptions Tokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.UserOptions User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityResult { public IdentityResult() { } public System.Collections.Generic.IEnumerable Errors { get { throw null; } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Identity.IdentityResult Success { get { throw null; } } public static Microsoft.AspNetCore.Identity.IdentityResult Failed(params Microsoft.AspNetCore.Identity.IdentityError[] errors) { throw null; } public override string ToString() { throw null; } @@ -294,9 +295,9 @@ namespace Microsoft.AspNetCore.Identity public partial class LockoutOptions { public LockoutOptions() { } - public bool AllowedForNewUsers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan DefaultLockoutTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MaxFailedAccessAttempts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowedForNewUsers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan DefaultLockoutTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MaxFailedAccessAttempts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public enum PasswordHasherCompatibilityMode { @@ -306,8 +307,8 @@ namespace Microsoft.AspNetCore.Identity public partial class PasswordHasherOptions { public PasswordHasherOptions() { } - public Microsoft.AspNetCore.Identity.PasswordHasherCompatibilityMode CompatibilityMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int IterationCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.PasswordHasherCompatibilityMode CompatibilityMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int IterationCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PasswordHasher : Microsoft.AspNetCore.Identity.IPasswordHasher where TUser : class { @@ -318,17 +319,17 @@ namespace Microsoft.AspNetCore.Identity public partial class PasswordOptions { public PasswordOptions() { } - public bool RequireDigit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RequiredLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RequiredUniqueChars { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireLowercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireNonAlphanumeric { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireUppercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RequireDigit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RequiredLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RequiredUniqueChars { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireLowercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireNonAlphanumeric { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireUppercase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PasswordValidator : Microsoft.AspNetCore.Identity.IPasswordValidator where TUser : class { public PasswordValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool IsDigit(char c) { throw null; } public virtual bool IsLetterOrDigit(char c) { throw null; } public virtual bool IsLower(char c) { throw null; } @@ -361,12 +362,12 @@ namespace Microsoft.AspNetCore.Identity { public RoleManager(Microsoft.AspNetCore.Identity.IRoleStore store, System.Collections.Generic.IEnumerable> roleValidators, Microsoft.AspNetCore.Identity.ILookupNormalizer keyNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors, Microsoft.Extensions.Logging.ILogger> logger) { } protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Linq.IQueryable Roles { get { throw null; } } - public System.Collections.Generic.IList> RoleValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Identity.IRoleStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList> RoleValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Identity.IRoleStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool SupportsQueryableRoles { get { throw null; } } public virtual bool SupportsRoleClaims { get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -406,20 +407,20 @@ namespace Microsoft.AspNetCore.Identity public partial class SignInOptions { public SignInOptions() { } - public bool RequireConfirmedAccount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireConfirmedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireConfirmedPhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RequireConfirmedAccount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireConfirmedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireConfirmedPhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SignInResult { public SignInResult() { } public static Microsoft.AspNetCore.Identity.SignInResult Failed { get { throw null; } } - public bool IsLockedOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public bool IsNotAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public bool IsLockedOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public bool IsNotAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Identity.SignInResult LockedOut { get { throw null; } } public static Microsoft.AspNetCore.Identity.SignInResult NotAllowed { get { throw null; } } - public bool RequiresTwoFactor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public bool RequiresTwoFactor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public static Microsoft.AspNetCore.Identity.SignInResult Success { get { throw null; } } public static Microsoft.AspNetCore.Identity.SignInResult TwoFactorRequired { get { throw null; } } public override string ToString() { throw null; } @@ -427,8 +428,8 @@ namespace Microsoft.AspNetCore.Identity public partial class StoreOptions { public StoreOptions() { } - public int MaxLengthForKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ProtectPersonalData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int MaxLengthForKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ProtectPersonalData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenOptions { @@ -437,19 +438,19 @@ namespace Microsoft.AspNetCore.Identity public static readonly string DefaultPhoneProvider; public static readonly string DefaultProvider; public TokenOptions() { } - public string AuthenticatorIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string AuthenticatorTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ChangeEmailTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ChangePhoneNumberTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EmailConfirmationTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PasswordResetTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.Dictionary ProviderMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticatorIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string AuthenticatorTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ChangeEmailTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ChangePhoneNumberTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EmailConfirmationTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PasswordResetTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.Dictionary ProviderMap { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenProviderDescriptor { public TokenProviderDescriptor(System.Type type) { } - public object ProviderInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ProviderType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object ProviderInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ProviderType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class TotpSecurityStampBasedTokenProvider : Microsoft.AspNetCore.Identity.IUserTwoFactorTokenProvider where TUser : class { @@ -471,8 +472,8 @@ namespace Microsoft.AspNetCore.Identity public partial class UserClaimsPrincipalFactory : Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory where TUser : class { public UserClaimsPrincipalFactory(Microsoft.AspNetCore.Identity.UserManager userManager, Microsoft.Extensions.Options.IOptions optionsAccessor) { } - public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Identity.UserManager UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Identity.UserManager UserManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task CreateAsync(TUser user) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -481,16 +482,16 @@ namespace Microsoft.AspNetCore.Identity public partial class UserClaimsPrincipalFactory : Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory where TUser : class where TRole : class { public UserClaimsPrincipalFactory(Microsoft.AspNetCore.Identity.UserManager userManager, Microsoft.AspNetCore.Identity.RoleManager roleManager, Microsoft.Extensions.Options.IOptions options) : base (default(Microsoft.AspNetCore.Identity.UserManager), default(Microsoft.Extensions.Options.IOptions)) { } - public Microsoft.AspNetCore.Identity.RoleManager RoleManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.RoleManager RoleManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] protected override System.Threading.Tasks.Task GenerateClaimsAsync(TUser user) { throw null; } } public partial class UserLoginInfo { public UserLoginInfo(string loginProvider, string providerKey, string displayName) { } - public string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UserManager : System.IDisposable where TUser : class { @@ -499,13 +500,13 @@ namespace Microsoft.AspNetCore.Identity public const string ResetPasswordTokenPurpose = "ResetPassword"; public UserManager(Microsoft.AspNetCore.Identity.IUserStore store, Microsoft.Extensions.Options.IOptions optionsAccessor, Microsoft.AspNetCore.Identity.IPasswordHasher passwordHasher, System.Collections.Generic.IEnumerable> userValidators, System.Collections.Generic.IEnumerable> passwordValidators, Microsoft.AspNetCore.Identity.ILookupNormalizer keyNormalizer, Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors, System.IServiceProvider services, Microsoft.Extensions.Logging.ILogger> logger) { } protected virtual System.Threading.CancellationToken CancellationToken { get { throw null; } } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Identity.IPasswordHasher PasswordHasher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList> PasswordValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected internal Microsoft.AspNetCore.Identity.IUserStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.ILookupNormalizer KeyNormalizer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.IdentityOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Identity.IPasswordHasher PasswordHasher { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList> PasswordValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected internal Microsoft.AspNetCore.Identity.IUserStore Store { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual bool SupportsQueryableUsers { get { throw null; } } public virtual bool SupportsUserAuthenticationTokens { get { throw null; } } public virtual bool SupportsUserAuthenticatorKey { get { throw null; } } @@ -520,7 +521,7 @@ namespace Microsoft.AspNetCore.Identity public virtual bool SupportsUserTwoFactor { get { throw null; } } public virtual bool SupportsUserTwoFactorRecoveryCodes { get { throw null; } } public virtual System.Linq.IQueryable Users { get { throw null; } } - public System.Collections.Generic.IList> UserValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList> UserValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task AccessFailedAsync(TUser user) { throw null; } public virtual System.Threading.Tasks.Task AddClaimAsync(TUser user, System.Security.Claims.Claim claim) { throw null; } @@ -679,13 +680,13 @@ namespace Microsoft.AspNetCore.Identity public partial class UserOptions { public UserOptions() { } - public string AllowedUserNameCharacters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireUniqueEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AllowedUserNameCharacters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireUniqueEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UserValidator : Microsoft.AspNetCore.Identity.IUserValidator where TUser : class { public UserValidator(Microsoft.AspNetCore.Identity.IdentityErrorDescriber errors = null) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber Describer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task ValidateAsync(Microsoft.AspNetCore.Identity.UserManager manager, TUser user) { throw null; } } diff --git a/src/Identity/Extensions.Core/src/IdentityBuilder.cs b/src/Identity/Extensions.Core/src/IdentityBuilder.cs index b7502237bc..357a0a7715 100644 --- a/src/Identity/Extensions.Core/src/IdentityBuilder.cs +++ b/src/Identity/Extensions.Core/src/IdentityBuilder.cs @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds an for the . + /// Adds an for the . /// /// The user validator type. /// The current instance. @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Identity => AddScoped(typeof(IUserValidator<>).MakeGenericType(UserType), typeof(TValidator)); /// - /// Adds an for the . + /// Adds an for the . /// /// The type of the claims principal factory. /// The current instance. @@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds an for the . + /// Adds an for the . /// /// The validator type used to validate passwords. /// The current instance. @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Identity => AddScoped(typeof(IPasswordValidator<>).MakeGenericType(UserType), typeof(TValidator)); /// - /// Adds an for the . + /// Adds an for the . /// /// The user store type. /// The current instance. @@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Identity => AddTokenProvider(providerName, typeof(TProvider)); /// - /// Adds a token provider for the . + /// Adds a token provider for the . /// /// The name of the provider to add. /// The type of the to add. @@ -134,11 +134,11 @@ namespace Microsoft.AspNetCore.Identity options.Tokens.ProviderMap[providerName] = new TokenProviderDescriptor(provider); }); Services.AddTransient(provider); - return this; + return this; } /// - /// Adds a for the . + /// Adds a for the . /// /// The type of the user manager to add. /// The current instance. @@ -172,7 +172,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds an for the . + /// Adds an for the . /// /// The role validator type. /// The current instance. @@ -191,7 +191,7 @@ namespace Microsoft.AspNetCore.Identity /// The personal data protector type. /// The personal data protector key ring type. /// The current instance. - public virtual IdentityBuilder AddPersonalDataProtection() + public virtual IdentityBuilder AddPersonalDataProtection() where TProtector : class,ILookupProtector where TKeyRing : class, ILookupProtectorKeyRing { @@ -202,7 +202,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds a for the . + /// Adds a for the . /// /// The role store. /// The current instance. @@ -216,7 +216,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Adds a for the . + /// Adds a for the . /// /// The type of the role manager to add. /// The current instance. @@ -238,5 +238,13 @@ namespace Microsoft.AspNetCore.Identity } return AddScoped(managerType, typeof(TRoleManager)); } + + /// + /// Adds a for the . + /// + /// The type of the user confirmation to add. + /// The current instance. + public virtual IdentityBuilder AddUserConfirmation() where TUserConfirmation : class + => AddScoped(typeof(IUserConfirmation<>).MakeGenericType(UserType), typeof(TUserConfirmation)); } } diff --git a/src/Identity/Extensions.Core/src/PrincipalExtensions.cs b/src/Identity/Extensions.Core/src/PrincipalExtensions.cs index fc33e19cf8..1c73573b3a 100644 --- a/src/Identity/Extensions.Core/src/PrincipalExtensions.cs +++ b/src/Identity/Extensions.Core/src/PrincipalExtensions.cs @@ -12,7 +12,7 @@ namespace System.Security.Claims public static class PrincipalExtensions { /// - /// Returns the value for the first claim of the specified type otherwise null the claim is not present. + /// Returns the value for the first claim of the specified type, otherwise null if the claim is not present. /// /// The instance this method extends. /// The claim type whose first value should be returned. @@ -28,4 +28,4 @@ namespace System.Security.Claims } } -} \ No newline at end of file +} diff --git a/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs b/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs index 9a58683d22..9b2b98a392 100644 --- a/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs +++ b/src/Identity/Extensions.Core/src/Rfc6238AuthenticationService.cs @@ -1,27 +1,32 @@ // 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.Diagnostics; using System.Net; using System.Security.Cryptography; +using System.Text; namespace Microsoft.AspNetCore.Identity { - using System; - using System.Text; - internal static class Rfc6238AuthenticationService { - private static readonly DateTime _unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly TimeSpan _timestep = TimeSpan.FromMinutes(3); private static readonly Encoding _encoding = new UTF8Encoding(false, true); +#if NETSTANDARD2_0 + private static readonly DateTime _unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); +#endif // Generates a new 80-bit security token public static byte[] GenerateRandomKey() { byte[] bytes = new byte[20]; +#if NETSTANDARD2_0 _rng.GetBytes(bytes); +#else + RandomNumberGenerator.Fill(bytes); +#endif return bytes; } @@ -63,7 +68,11 @@ namespace Microsoft.AspNetCore.Identity // More info: https://tools.ietf.org/html/rfc6238#section-4 private static ulong GetCurrentTimeStepNumber() { +#if NETSTANDARD2_0 var delta = DateTime.UtcNow - _unixEpoch; +#else + var delta = DateTimeOffset.UtcNow - DateTimeOffset.UnixEpoch; +#endif return (ulong)(delta.Ticks / _timestep.Ticks); } diff --git a/src/Identity/Extensions.Core/src/UserManager.cs b/src/Identity/Extensions.Core/src/UserManager.cs index 4116045c4a..ddbf98f5df 100644 --- a/src/Identity/Extensions.Core/src/UserManager.cs +++ b/src/Identity/Extensions.Core/src/UserManager.cs @@ -43,7 +43,9 @@ namespace Microsoft.AspNetCore.Identity private TimeSpan _defaultLockout = TimeSpan.Zero; private bool _disposed; +#if NETSTANDARD2_0 private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); +#endif private IServiceProvider _services; /// @@ -113,7 +115,7 @@ namespace Microsoft.AspNetCore.Identity RegisterTokenProvider(providerName, provider); } } - } + } if (Options.Stores.ProtectPersonalData) { @@ -161,7 +163,7 @@ namespace Microsoft.AspNetCore.Identity /// The used to normalize things like user and role names. /// public ILookupNormalizer KeyNormalizer { get; set; } - + /// /// The used to generate error messages. /// @@ -617,7 +619,7 @@ namespace Microsoft.AspNetCore.Identity /// A normalized value representing the specified . public virtual string NormalizeEmail(string email) => (KeyNormalizer == null) ? email : KeyNormalizer.NormalizeEmail(email); - + private string ProtectPersonalData(string data) { if (Options.Stores.ProtectPersonalData) @@ -861,7 +863,7 @@ namespace Microsoft.AspNetCore.Identity throw new ArgumentNullException(nameof(user)); } var stamp = await securityStore.GetSecurityStampAsync(user, CancellationToken); - if (stamp == null) + if (stamp == null) { Logger.LogWarning(15, "GetSecurityStampAsync for user {userId} failed because stamp was null.", await GetUserIdAsync(user)); throw new InvalidOperationException(Resources.NullSecurityStamp); @@ -1898,7 +1900,7 @@ namespace Microsoft.AspNetCore.Identity } /// - /// Returns a flag indicating whether the specified his locked out, + /// Returns a flag indicating whether the specified is locked out, /// as an asynchronous operation. /// /// The user whose locked out status should be retrieved. @@ -2428,7 +2430,11 @@ namespace Microsoft.AspNetCore.Identity private static string NewSecurityStamp() { byte[] bytes = new byte[20]; +#if NETSTANDARD2_0 _rng.GetBytes(bytes); +#else + RandomNumberGenerator.Fill(bytes); +#endif return Base32.ToBase32(bytes); } diff --git a/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netcoreapp.cs b/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netcoreapp.cs index 5ea5d5f233..6fe6cf837f 100644 --- a/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netcoreapp.cs +++ b/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netcoreapp.cs @@ -11,10 +11,10 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityRoleClaim where TKey : System.IEquatable { public IdentityRoleClaim() { } - public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void InitializeFromClaim(System.Security.Claims.Claim other) { } public virtual System.Security.Claims.Claim ToClaim() { throw null; } } @@ -22,10 +22,10 @@ namespace Microsoft.AspNetCore.Identity { public IdentityRole() { } public IdentityRole(string roleName) { } - public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string NormalizedName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string NormalizedName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string ToString() { throw null; } } public partial class IdentityUser : Microsoft.AspNetCore.Identity.IdentityUser @@ -36,68 +36,68 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityUserClaim where TKey : System.IEquatable { public IdentityUserClaim() { } - public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void InitializeFromClaim(System.Security.Claims.Claim claim) { } public virtual System.Security.Claims.Claim ToClaim() { throw null; } } public partial class IdentityUserLogin where TKey : System.IEquatable { public IdentityUserLogin() { } - public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityUserRole where TKey : System.IEquatable { public IdentityUserRole() { } - public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityUserToken where TKey : System.IEquatable { public IdentityUserToken() { } - public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityUser where TKey : System.IEquatable { public IdentityUser() { } public IdentityUser(string userName) { } - public virtual int AccessFailedCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual int AccessFailedCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual bool EmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool EmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual bool LockoutEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.DateTimeOffset? LockoutEnd { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string NormalizedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string NormalizedUserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string PasswordHash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual bool LockoutEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.DateTimeOffset? LockoutEnd { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string NormalizedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string NormalizedUserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string PasswordHash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual bool PhoneNumberConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string SecurityStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool PhoneNumberConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string SecurityStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual bool TwoFactorEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool TwoFactorEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string UserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string UserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string ToString() { throw null; } } public abstract partial class RoleStoreBase : Microsoft.AspNetCore.Identity.IQueryableRoleStore, Microsoft.AspNetCore.Identity.IRoleClaimStore, Microsoft.AspNetCore.Identity.IRoleStore, System.IDisposable where TRole : Microsoft.AspNetCore.Identity.IdentityRole where TKey : System.IEquatable where TUserRole : Microsoft.AspNetCore.Identity.IdentityUserRole, new() where TRoleClaim : Microsoft.AspNetCore.Identity.IdentityRoleClaim, new() { public RoleStoreBase(Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.Linq.IQueryable Roles { get; } public abstract System.Threading.Tasks.Task AddClaimAsync(TRole role, System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); public virtual TKey ConvertIdFromString(string id) { throw null; } @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Identity public abstract partial class UserStoreBase : Microsoft.AspNetCore.Identity.IQueryableUserStore, Microsoft.AspNetCore.Identity.IUserAuthenticationTokenStore, Microsoft.AspNetCore.Identity.IUserAuthenticatorKeyStore, Microsoft.AspNetCore.Identity.IUserClaimStore, Microsoft.AspNetCore.Identity.IUserEmailStore, Microsoft.AspNetCore.Identity.IUserLockoutStore, Microsoft.AspNetCore.Identity.IUserLoginStore, Microsoft.AspNetCore.Identity.IUserPasswordStore, Microsoft.AspNetCore.Identity.IUserPhoneNumberStore, Microsoft.AspNetCore.Identity.IUserSecurityStampStore, Microsoft.AspNetCore.Identity.IUserStore, Microsoft.AspNetCore.Identity.IUserTwoFactorRecoveryCodeStore, Microsoft.AspNetCore.Identity.IUserTwoFactorStore, System.IDisposable where TUser : Microsoft.AspNetCore.Identity.IdentityUser where TKey : System.IEquatable where TUserClaim : Microsoft.AspNetCore.Identity.IdentityUserClaim, new() where TUserLogin : Microsoft.AspNetCore.Identity.IdentityUserLogin, new() where TUserToken : Microsoft.AspNetCore.Identity.IdentityUserToken, new() { public UserStoreBase(Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.Linq.IQueryable Users { get; } public abstract System.Threading.Tasks.Task AddClaimsAsync(TUser user, System.Collections.Generic.IEnumerable claims, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); public abstract System.Threading.Tasks.Task AddLoginAsync(TUser user, Microsoft.AspNetCore.Identity.UserLoginInfo login, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); diff --git a/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netstandard2.0.cs b/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netstandard2.0.cs index 5ea5d5f233..6fe6cf837f 100644 --- a/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netstandard2.0.cs +++ b/src/Identity/Extensions.Stores/ref/Microsoft.Extensions.Identity.Stores.netstandard2.0.cs @@ -11,10 +11,10 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityRoleClaim where TKey : System.IEquatable { public IdentityRoleClaim() { } - public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void InitializeFromClaim(System.Security.Claims.Claim other) { } public virtual System.Security.Claims.Claim ToClaim() { throw null; } } @@ -22,10 +22,10 @@ namespace Microsoft.AspNetCore.Identity { public IdentityRole() { } public IdentityRole(string roleName) { } - public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string NormalizedName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string NormalizedName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string ToString() { throw null; } } public partial class IdentityUser : Microsoft.AspNetCore.Identity.IdentityUser @@ -36,68 +36,68 @@ namespace Microsoft.AspNetCore.Identity public partial class IdentityUserClaim where TKey : System.IEquatable { public IdentityUserClaim() { } - public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ClaimValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual int Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void InitializeFromClaim(System.Security.Claims.Claim claim) { } public virtual System.Security.Claims.Claim ToClaim() { throw null; } } public partial class IdentityUserLogin where TKey : System.IEquatable { public IdentityUserLogin() { } - public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ProviderKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityUserRole where TKey : System.IEquatable { public IdentityUserRole() { } - public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual TKey RoleId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityUserToken where TKey : System.IEquatable { public IdentityUserToken() { } - public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string LoginProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual TKey UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class IdentityUser where TKey : System.IEquatable { public IdentityUser() { } public IdentityUser(string userName) { } - public virtual int AccessFailedCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual int AccessFailedCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string ConcurrencyStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual bool EmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool EmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual bool LockoutEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.DateTimeOffset? LockoutEnd { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string NormalizedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string NormalizedUserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string PasswordHash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual TKey Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual bool LockoutEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.DateTimeOffset? LockoutEnd { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string NormalizedEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string NormalizedUserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string PasswordHash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual bool PhoneNumberConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string SecurityStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool PhoneNumberConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string SecurityStamp { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.PersonalDataAttribute] - public virtual bool TwoFactorEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool TwoFactorEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Identity.ProtectedPersonalDataAttribute] - public virtual string UserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string UserName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string ToString() { throw null; } } public abstract partial class RoleStoreBase : Microsoft.AspNetCore.Identity.IQueryableRoleStore, Microsoft.AspNetCore.Identity.IRoleClaimStore, Microsoft.AspNetCore.Identity.IRoleStore, System.IDisposable where TRole : Microsoft.AspNetCore.Identity.IdentityRole where TKey : System.IEquatable where TUserRole : Microsoft.AspNetCore.Identity.IdentityUserRole, new() where TRoleClaim : Microsoft.AspNetCore.Identity.IdentityRoleClaim, new() { public RoleStoreBase(Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.Linq.IQueryable Roles { get; } public abstract System.Threading.Tasks.Task AddClaimAsync(TRole role, System.Security.Claims.Claim claim, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); public virtual TKey ConvertIdFromString(string id) { throw null; } @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Identity public abstract partial class UserStoreBase : Microsoft.AspNetCore.Identity.IQueryableUserStore, Microsoft.AspNetCore.Identity.IUserAuthenticationTokenStore, Microsoft.AspNetCore.Identity.IUserAuthenticatorKeyStore, Microsoft.AspNetCore.Identity.IUserClaimStore, Microsoft.AspNetCore.Identity.IUserEmailStore, Microsoft.AspNetCore.Identity.IUserLockoutStore, Microsoft.AspNetCore.Identity.IUserLoginStore, Microsoft.AspNetCore.Identity.IUserPasswordStore, Microsoft.AspNetCore.Identity.IUserPhoneNumberStore, Microsoft.AspNetCore.Identity.IUserSecurityStampStore, Microsoft.AspNetCore.Identity.IUserStore, Microsoft.AspNetCore.Identity.IUserTwoFactorRecoveryCodeStore, Microsoft.AspNetCore.Identity.IUserTwoFactorStore, System.IDisposable where TUser : Microsoft.AspNetCore.Identity.IdentityUser where TKey : System.IEquatable where TUserClaim : Microsoft.AspNetCore.Identity.IdentityUserClaim, new() where TUserLogin : Microsoft.AspNetCore.Identity.IdentityUserLogin, new() where TUserToken : Microsoft.AspNetCore.Identity.IdentityUserToken, new() { public UserStoreBase(Microsoft.AspNetCore.Identity.IdentityErrorDescriber describer) { } - public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.IdentityErrorDescriber ErrorDescriber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.Linq.IQueryable Users { get; } public abstract System.Threading.Tasks.Task AddClaimsAsync(TUser user, System.Collections.Generic.IEnumerable claims, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); public abstract System.Threading.Tasks.Task AddLoginAsync(TUser user, Microsoft.AspNetCore.Identity.UserLoginInfo login, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); diff --git a/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.csproj b/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.csproj index 51b7eca6c4..813c7c4dff 100644 --- a/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.csproj +++ b/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.csproj @@ -5,7 +5,6 @@ - diff --git a/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.netcoreapp.cs b/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.netcoreapp.cs index 73b686d1e6..4f25f3b9fa 100644 --- a/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.netcoreapp.cs +++ b/src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.netcoreapp.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Identity.UI public sealed partial class UIFrameworkAttribute : System.Attribute { public UIFrameworkAttribute(string uiFramework) { } - public string UIFramework { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string UIFramework { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Identity.UI.Services @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected ConfirmEmailChangeModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string userId, string email, string code) { throw null; } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected ConfirmEmailModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string userId, string code) { throw null; } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -52,11 +52,11 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { public ExternalLoginModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ExternalLoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ExternalLoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual Microsoft.AspNetCore.Mvc.IActionResult OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnGetCallbackAsync(string returnUrl = null, string remoteError = null) { throw null; } public virtual Microsoft.AspNetCore.Mvc.IActionResult OnPost(string provider, string returnUrl = null) { throw null; } @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -80,14 +80,14 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected ForgotPasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ForgotPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ForgotPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel { public InputModel() { } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -101,11 +101,11 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected LoginModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.LoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.LoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(string returnUrl = null) { throw null; } public partial class InputModel @@ -113,12 +113,12 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Remember me?")] - public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -126,21 +126,21 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected LoginWith2faModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.LoginWith2faModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.LoginWith2faModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(bool rememberMe, string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(bool rememberMe, string returnUrl = null) { throw null; } public partial class InputModel { public InputModel() { } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Remember this machine")] - public bool RememberMachine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RememberMachine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Text)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Authenticator code")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(7, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string TwoFactorCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string TwoFactorCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -148,8 +148,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected LoginWithRecoveryCodeModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.LoginWithRecoveryCodeModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.LoginWithRecoveryCodeModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(string returnUrl = null) { throw null; } public partial class InputModel @@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Text)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Recovery Code")] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string RecoveryCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RecoveryCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -173,19 +173,19 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal public partial class RegisterConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public RegisterConfirmationModel() { } - public bool DisplayConfirmAccountLink { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EmailConfirmationUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool DisplayConfirmAccountLink { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EmailConfirmationUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string email, string returnUrl = null) { throw null; } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] public abstract partial class RegisterModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected RegisterModel() { } - public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.RegisterModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.RegisterModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(string returnUrl = null) { throw null; } public partial class InputModel @@ -194,16 +194,32 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal [System.ComponentModel.DataAnnotations.CompareAttribute("Password", ErrorMessage="The password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Email")] [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + } + } + [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] + public abstract partial class ResendEmailConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel + { + protected ResendEmailConfirmationModel() { } + [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ResendEmailConfirmationModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual void OnGet() { } + public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } + public partial class InputModel + { + public InputModel() { } + [System.ComponentModel.DataAnnotations.EmailAddressAttribute] + [System.ComponentModel.DataAnnotations.RequiredAttribute] + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -217,25 +233,25 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { protected ResetPasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ResetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ResetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual Microsoft.AspNetCore.Mvc.IActionResult OnGet(string code = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel { public InputModel() { } [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.CompareAttribute("Password", ErrorMessage="The password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } } @@ -245,9 +261,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal { protected ChangePasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.ChangePasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.ChangePasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -256,24 +272,24 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.CompareAttribute("NewPassword", ErrorMessage="The new password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm new password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="New password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Current password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string OldPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string OldPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class DeletePersonalDataModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected DeletePersonalDataModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.DeletePersonalDataModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequirePassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.DeletePersonalDataModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequirePassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -281,14 +297,14 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class Disable2faModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected Disable2faModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -301,12 +317,12 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal public abstract partial class EmailModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected EmailModel() { } - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.EmailModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsEmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.EmailModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsEmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostChangeEmailAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostSendVerificationEmailAsync() { throw null; } @@ -316,20 +332,20 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="New email")] [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string NewEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string NewEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public partial class EnableAuthenticatorModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public EnableAuthenticatorModel() { } - public string AuthenticatorUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticatorUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.EnableAuthenticatorModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.EnableAuthenticatorModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SharedKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SharedKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -339,17 +355,17 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Verification Code")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(7, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class ExternalLoginsModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected ExternalLoginsModel() { } - public System.Collections.Generic.IList CurrentLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList OtherLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShowRemoveButton { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList CurrentLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList OtherLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShowRemoveButton { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnGetLinkLoginCallbackAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostLinkLoginAsync(string provider) { throw null; } @@ -359,9 +375,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal { protected GenerateRecoveryCodesModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -369,10 +385,10 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal { protected IndexModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.IndexModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.IndexModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Username { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Username { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -380,7 +396,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Phone number")] [System.ComponentModel.DataAnnotations.PhoneAttribute] - public string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public static partial class ManageNavPages @@ -412,7 +428,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal { protected ResetAuthenticatorModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -420,9 +436,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal { protected SetPasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.SetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal.SetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -431,33 +447,33 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.CompareAttribute("NewPassword", ErrorMessage="The new password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm new password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="New password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public partial class ShowRecoveryCodesModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public ShowRecoveryCodesModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.IActionResult OnGet() { throw null; } } public abstract partial class TwoFactorAuthenticationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected TwoFactorAuthenticationModel() { } - public bool HasAuthenticator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool HasAuthenticator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public bool Is2faEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsMachineRemembered { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RecoveryCodesLeft { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Is2faEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsMachineRemembered { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RecoveryCodesLeft { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -469,7 +485,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Internal public partial class ErrorModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public ErrorModel() { } - public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool ShowRequestId { get { throw null; } } public void OnGet() { } } @@ -486,7 +502,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected ConfirmEmailChangeModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string userId, string email, string code) { throw null; } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -494,7 +510,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected ConfirmEmailModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string userId, string code) { throw null; } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -502,11 +518,11 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { public ExternalLoginModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ExternalLoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ExternalLoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProviderDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual Microsoft.AspNetCore.Mvc.IActionResult OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnGetCallbackAsync(string returnUrl = null, string remoteError = null) { throw null; } public virtual Microsoft.AspNetCore.Mvc.IActionResult OnPost(string provider, string returnUrl = null) { throw null; } @@ -516,7 +532,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -530,14 +546,14 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected ForgotPasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ForgotPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ForgotPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel { public InputModel() { } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -551,11 +567,11 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected LoginModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LoginModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(string returnUrl = null) { throw null; } public partial class InputModel @@ -563,12 +579,12 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Remember me?")] - public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -576,21 +592,21 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected LoginWith2faModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LoginWith2faModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LoginWith2faModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RememberMe { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(bool rememberMe, string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(bool rememberMe, string returnUrl = null) { throw null; } public partial class InputModel { public InputModel() { } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Remember this machine")] - public bool RememberMachine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RememberMachine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Text)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Authenticator code")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(7, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string TwoFactorCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string TwoFactorCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -598,8 +614,8 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected LoginWithRecoveryCodeModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LoginWithRecoveryCodeModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LoginWithRecoveryCodeModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(string returnUrl = null) { throw null; } public partial class InputModel @@ -609,7 +625,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Text)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Recovery Code")] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string RecoveryCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RecoveryCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -623,19 +639,19 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal public partial class RegisterConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public RegisterConfirmationModel() { } - public bool DisplayConfirmAccountLink { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string EmailConfirmationUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool DisplayConfirmAccountLink { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string EmailConfirmationUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string email, string returnUrl = null) { throw null; } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] public abstract partial class RegisterModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected RegisterModel() { } - public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList ExternalLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.RegisterModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.RegisterModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync(string returnUrl = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync(string returnUrl = null) { throw null; } public partial class InputModel @@ -644,16 +660,32 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal [System.ComponentModel.DataAnnotations.CompareAttribute("Password", ErrorMessage="The password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Email")] [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + } + } + [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] + public abstract partial class ResendEmailConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel + { + protected ResendEmailConfirmationModel() { } + [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ResendEmailConfirmationModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual void OnGet() { } + public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } + public partial class InputModel + { + public InputModel() { } + [System.ComponentModel.DataAnnotations.EmailAddressAttribute] + [System.ComponentModel.DataAnnotations.RequiredAttribute] + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } [Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute] @@ -667,25 +699,25 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { protected ResetPasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ResetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ResetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual Microsoft.AspNetCore.Mvc.IActionResult OnGet(string code = null) { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel { public InputModel() { } [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.CompareAttribute("Password", ErrorMessage="The password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } } @@ -695,9 +727,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal { protected ChangePasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.ChangePasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.ChangePasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -706,24 +738,24 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.CompareAttribute("NewPassword", ErrorMessage="The new password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm new password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="New password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Current password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string OldPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string OldPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class DeletePersonalDataModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected DeletePersonalDataModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.DeletePersonalDataModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequirePassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.DeletePersonalDataModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequirePassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -731,14 +763,14 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Password { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class Disable2faModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected Disable2faModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -751,12 +783,12 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal public abstract partial class EmailModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected EmailModel() { } - public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.EmailModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsEmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.EmailModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsEmailConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostChangeEmailAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostSendVerificationEmailAsync() { throw null; } @@ -766,20 +798,20 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="New email")] [System.ComponentModel.DataAnnotations.EmailAddressAttribute] [System.ComponentModel.DataAnnotations.RequiredAttribute] - public string NewEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string NewEmail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public partial class EnableAuthenticatorModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public EnableAuthenticatorModel() { } - public string AuthenticatorUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticatorUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.EnableAuthenticatorModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.EnableAuthenticatorModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SharedKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SharedKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -789,17 +821,17 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Verification Code")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(7, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class ExternalLoginsModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected ExternalLoginsModel() { } - public System.Collections.Generic.IList CurrentLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList OtherLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShowRemoveButton { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList CurrentLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList OtherLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShowRemoveButton { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnGetLinkLoginCallbackAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostLinkLoginAsync(string provider) { throw null; } @@ -809,9 +841,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal { protected GenerateRecoveryCodesModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -819,10 +851,10 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal { protected IndexModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.IndexModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.IndexModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Username { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Username { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -830,7 +862,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal public InputModel() { } [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Phone number")] [System.ComponentModel.DataAnnotations.PhoneAttribute] - public string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PhoneNumber { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public static partial class ManageNavPages @@ -862,7 +894,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal { protected ResetAuthenticatorModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGet() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -870,9 +902,9 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal { protected SetPasswordModel() { } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.SetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal.SetPasswordModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } public partial class InputModel @@ -881,33 +913,33 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal [System.ComponentModel.DataAnnotations.CompareAttribute("NewPassword", ErrorMessage="The new password and confirmation password do not match.")] [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="Confirm new password")] - public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfirmPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.DataAnnotations.DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType.Password)] [System.ComponentModel.DataAnnotations.DisplayAttribute(Name="New password")] [System.ComponentModel.DataAnnotations.RequiredAttribute] [System.ComponentModel.DataAnnotations.StringLengthAttribute(100, ErrorMessage="The {0} must be at least {2} and at max {1} characters long.", MinimumLength=6)] - public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string NewPassword { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public partial class ShowRecoveryCodesModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public ShowRecoveryCodesModel() { } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string[] RecoveryCodes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.IActionResult OnGet() { throw null; } } public abstract partial class TwoFactorAuthenticationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { protected TwoFactorAuthenticationModel() { } - public bool HasAuthenticator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool HasAuthenticator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.BindPropertyAttribute] - public bool Is2faEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsMachineRemembered { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RecoveryCodesLeft { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Is2faEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsMachineRemembered { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RecoveryCodesLeft { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.TempDataAttribute] - public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string StatusMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task OnGetAsync() { throw null; } public virtual System.Threading.Tasks.Task OnPostAsync() { throw null; } } @@ -919,7 +951,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Internal public partial class ErrorModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel { public ErrorModel() { } - public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RequestId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool ShowRequestId { get { throw null; } } public void OnGet() { } } diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml index e0053be7fd..f73e2fe556 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml @@ -17,7 +17,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml.cs index df1df133f8..549e6029cb 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml.cs +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ExternalLogin.cshtml.cs @@ -197,13 +197,6 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal { _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); - // If account confirmation is required, we need to show the link if we don't have a real email sender - if (_userManager.Options.SignIn.RequireConfirmedAccount) - { - return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email }); - } - - await _signInManager.SignInAsync(user, isPersistent: false); var userId = await _userManager.GetUserIdAsync(user); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); @@ -215,6 +208,14 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by clicking here."); + + // If account confirmation is required, we need to show the link if we don't have a real email sender + if (_userManager.Options.SignIn.RequireConfirmedAccount) + { + return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email }); + } + + await _signInManager.SignInAsync(user, isPersistent: false); return LocalRedirect(returnUrl); } diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ForgotPassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ForgotPassword.cshtml index b938724210..7541125984 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ForgotPassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ForgotPassword.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Login.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Login.cshtml index dddca7fae7..8f4559fb78 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Login.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Login.cshtml @@ -12,7 +12,7 @@

Use a local account to log in.


-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWith2fa.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWith2fa.cshtml index 94242c929e..28b23ae8e1 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWith2fa.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWith2fa.cshtml @@ -11,7 +11,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWithRecoveryCode.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWithRecoveryCode.cshtml index abaad2a4d4..9f0e526bcf 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWithRecoveryCode.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/LoginWithRecoveryCode.cshtml @@ -13,7 +13,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/ChangePassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/ChangePassword.cshtml index 701c1ea457..0cdc9c97a7 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/ChangePassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/ChangePassword.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DeletePersonalData.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DeletePersonalData.cshtml index e1a2b7a8a2..4939c7fd5a 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DeletePersonalData.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DeletePersonalData.cshtml @@ -16,7 +16,7 @@
-
+
@if (Model.RequirePassword) {
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DownloadPersonalData.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DownloadPersonalData.cshtml.cs index 5152d01e35..d0fdadaf93 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DownloadPersonalData.cshtml.cs +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/DownloadPersonalData.cshtml.cs @@ -5,11 +5,11 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal { @@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal personalData.Add($"Authenticator Key", await _userManager.GetAuthenticatorKeyAsync(user)); Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json"); - return new FileContentResult(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(personalData)), "text/json"); + return new FileContentResult(JsonSerializer.SerializeToUtf8Bytes(personalData), "application/json"); } } } diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/EnableAuthenticator.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/EnableAuthenticator.cshtml.cs index e086540e59..75e5efdf26 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/EnableAuthenticator.cshtml.cs +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/EnableAuthenticator.cshtml.cs @@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Manage.Internal return Page(); } - // Strip spaces and hypens + // Strip spaces and hyphens var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync( diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/Index.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/Index.cshtml index 19ac1a296e..2adbdecf6f 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/Index.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/Index.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/SetPassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/SetPassword.cshtml index 31632c3860..e82ce19df5 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/SetPassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Manage/SetPassword.cshtml @@ -14,7 +14,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Register.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Register.cshtml index cf6a7c6e96..78415afe1a 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Register.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Register.cshtml @@ -11,7 +11,7 @@

Create a new account.


-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml new file mode 100644 index 0000000000..910891fb46 --- /dev/null +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml @@ -0,0 +1,26 @@ +@page +@model ResendEmailConfirmationModel +@{ + ViewData["Title"] = "Resend email confirmation"; +} + +

@ViewData["Title"]

+

Enter your email.

+
+
+
+ +
+
+ + + +
+ + +
+
+ +@section Scripts { + +} diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml.cs new file mode 100644 index 0000000000..d1d2ef7846 --- /dev/null +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml.cs @@ -0,0 +1,106 @@ +// 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.ComponentModel.DataAnnotations; +using System.Text; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity.UI.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.WebUtilities; + +namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal +{ + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + [AllowAnonymous] + [IdentityDefaultUI(typeof(ResendEmailConfirmationModel<>))] + public abstract class ResendEmailConfirmationModel : PageModel + { + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + [BindProperty] + public InputModel Input { get; set; } + + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public class InputModel + { + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + [Required] + [EmailAddress] + public string Email { get; set; } + } + + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public virtual void OnGet() => throw new NotImplementedException(); + + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public virtual Task OnPostAsync() => throw new NotImplementedException(); + } + + internal class ResendEmailConfirmationModel : ResendEmailConfirmationModel where TUser : class + { + private readonly UserManager _userManager; + private readonly IEmailSender _emailSender; + + public ResendEmailConfirmationModel(UserManager userManager, IEmailSender emailSender) + { + _userManager = userManager; + _emailSender = emailSender; + } + + public override void OnGet() + { + } + + public override async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + + var user = await _userManager.FindByEmailAsync(Input.Email); + if (user == null) + { + ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email."); + return Page(); + } + + var userId = await _userManager.GetUserIdAsync(user); + var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); + code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); + var callbackUrl = Url.Page( + "/Account/ConfirmEmail", + pageHandler: null, + values: new { userId = userId, code = code }, + protocol: Request.Scheme); + await _emailSender.SendEmailAsync( + Input.Email, + "Confirm your email", + $"Please confirm your account by clicking here."); + + ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email."); + return Page(); + } + } +} diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResetPassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResetPassword.cshtml index 5ccb61edcf..97629b27cd 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResetPassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResetPassword.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml index d92664c31c..7579138faa 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml @@ -17,7 +17,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml.cs index c584cacd8e..62df7a64f4 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml.cs +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ExternalLogin.cshtml.cs @@ -116,10 +116,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal _emailSender = emailSender; } - public override IActionResult OnGet() - { - return RedirectToPage("./Login"); - } + public override IActionResult OnGet() => RedirectToPage("./Login"); public override IActionResult OnPost(string provider, string returnUrl = null) { @@ -197,13 +194,6 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal { _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider); - // If account confirmation is required, we need to show the link if we don't have a real email sender - if (_userManager.Options.SignIn.RequireConfirmedAccount) - { - return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email }); - } - - await _signInManager.SignInAsync(user, isPersistent: false); var userId = await _userManager.GetUserIdAsync(user); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); @@ -216,6 +206,13 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by clicking here."); + // If account confirmation is required, we need to show the link if we don't have a real email sender + if (_userManager.Options.SignIn.RequireConfirmedAccount) + { + return RedirectToPage("./RegisterConfirmation", new { Email = Input.Email }); + } + + await _signInManager.SignInAsync(user, isPersistent: false); return LocalRedirect(returnUrl); } } diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ForgotPassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ForgotPassword.cshtml index d3eb7ce65d..4570844df8 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ForgotPassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ForgotPassword.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Login.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Login.cshtml index b98655e0f6..47b8750956 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Login.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Login.cshtml @@ -12,7 +12,7 @@

Use a local account to log in.


-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWith2fa.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWith2fa.cshtml index b5508902f6..5cc2aa2d13 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWith2fa.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWith2fa.cshtml @@ -11,7 +11,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWithRecoveryCode.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWithRecoveryCode.cshtml index 957f72b00f..5947903f87 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWithRecoveryCode.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/LoginWithRecoveryCode.cshtml @@ -13,7 +13,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/ChangePassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/ChangePassword.cshtml index 07e23b117c..4d5dda19ec 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/ChangePassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/ChangePassword.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DeletePersonalData.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DeletePersonalData.cshtml index e1896604ff..abcd16a82f 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DeletePersonalData.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DeletePersonalData.cshtml @@ -15,7 +15,7 @@
-
+
@if (Model.RequirePassword) {
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DownloadPersonalData.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DownloadPersonalData.cshtml.cs index 8529e3b171..38d077f014 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DownloadPersonalData.cshtml.cs +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/DownloadPersonalData.cshtml.cs @@ -5,11 +5,11 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal { @@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal personalData.Add($"Authenticator Key", await _userManager.GetAuthenticatorKeyAsync(user)); Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json"); - return new FileContentResult(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(personalData)), "text/json"); + return new FileContentResult(JsonSerializer.SerializeToUtf8Bytes(personalData), "application/json"); } } } diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs index 798b8a8671..069f6c3d7b 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/EnableAuthenticator.cshtml.cs @@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal return Page(); } - // Strip spaces and hypens + // Strip spaces and hyphens var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync( diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/Index.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/Index.cshtml index dd25959817..1c125b18f7 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/Index.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/Index.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/SetPassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/SetPassword.cshtml index 2a42c34f36..593526746e 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/SetPassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Manage/SetPassword.cshtml @@ -14,7 +14,7 @@
-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Register.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Register.cshtml index 99620a5836..0a2f84f935 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Register.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Register.cshtml @@ -11,7 +11,7 @@

Create a new account.


-
+
diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResendEmailConfirmation.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResendEmailConfirmation.cshtml new file mode 100644 index 0000000000..16d11e9d8e --- /dev/null +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResendEmailConfirmation.cshtml @@ -0,0 +1,26 @@ +@page +@model ResendEmailConfirmationModel +@{ + ViewData["Title"] = "Resend email confirmation"; +} + +

@ViewData["Title"]

+

Enter your email.

+
+
+
+ +
+
+ + + +
+ + +
+
+ +@section Scripts { + +} diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResendEmailConfirmation.cshtml.cs b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResendEmailConfirmation.cshtml.cs new file mode 100644 index 0000000000..559ce47bc5 --- /dev/null +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResendEmailConfirmation.cshtml.cs @@ -0,0 +1,106 @@ +// 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.ComponentModel.DataAnnotations; +using System.Text; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity.UI.Services; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.WebUtilities; + +namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal +{ + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + [AllowAnonymous] + [IdentityDefaultUI(typeof(ResendEmailConfirmationModel<>))] + public abstract class ResendEmailConfirmationModel : PageModel + { + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + [BindProperty] + public InputModel Input { get; set; } + + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public class InputModel + { + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + [Required] + [EmailAddress] + public string Email { get; set; } + } + + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public virtual void OnGet() => throw new NotImplementedException(); + + /// + /// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + public virtual Task OnPostAsync() => throw new NotImplementedException(); + } + + internal class ResendEmailConfirmationModel : ResendEmailConfirmationModel where TUser : class + { + private readonly UserManager _userManager; + private readonly IEmailSender _emailSender; + + public ResendEmailConfirmationModel(UserManager userManager, IEmailSender emailSender) + { + _userManager = userManager; + _emailSender = emailSender; + } + + public override void OnGet() + { + } + + public override async Task OnPostAsync() + { + if (!ModelState.IsValid) + { + return Page(); + } + + var user = await _userManager.FindByEmailAsync(Input.Email); + if (user == null) + { + ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email."); + return Page(); + } + + var userId = await _userManager.GetUserIdAsync(user); + var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); + code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); + var callbackUrl = Url.Page( + "/Account/ConfirmEmail", + pageHandler: null, + values: new { userId = userId, code = code }, + protocol: Request.Scheme); + await _emailSender.SendEmailAsync( + Input.Email, + "Confirm your email", + $"Please confirm your account by clicking here."); + + ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email."); + return Page(); + } + } +} diff --git a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResetPassword.cshtml b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResetPassword.cshtml index 3202efb8ec..953261844b 100644 --- a/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResetPassword.cshtml +++ b/src/Identity/UI/src/Areas/Identity/Pages/V4/Account/ResetPassword.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj index d803f42f5a..f5a122a355 100644 --- a/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj +++ b/src/Identity/UI/src/Microsoft.AspNetCore.Identity.UI.csproj @@ -36,7 +36,6 @@ - diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml index 6b2de21b43..23593ab99a 100644 --- a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml +++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Manage/Index.cshtml @@ -9,7 +9,7 @@
-
+
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml index 259373e966..42297ce4d6 100644 --- a/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml +++ b/src/Identity/samples/IdentitySample.DefaultUI/Areas/Identity/Pages/Account/Register.cshtml @@ -11,7 +11,7 @@

Create a new account.


-
+
diff --git a/src/Identity/samples/IdentitySample.DefaultUI/web.config b/src/Identity/samples/IdentitySample.DefaultUI/web.config index f7ac679334..6d25118e27 100644 --- a/src/Identity/samples/IdentitySample.DefaultUI/web.config +++ b/src/Identity/samples/IdentitySample.DefaultUI/web.config @@ -2,8 +2,12 @@ - + - + + + + + \ No newline at end of file diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml index 0bd3f75c1a..c9151a4239 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/ExternalLoginConfirmation.cshtml @@ -9,7 +9,7 @@

Association Form


-
+

You've successfully authenticated with @ViewData["ProviderDisplayName"]. diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml index 5603e2a08c..74f769a750 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/ForgotPassword.cshtml @@ -11,7 +11,7 @@ @*

Enter your email.


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/Login.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/Login.cshtml index b8803908e1..92e5a4a89a 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/Login.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/Login.cshtml @@ -15,7 +15,7 @@

Use a local account to log in.


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/Register.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/Register.cshtml index 44e11d6955..f2d23a465c 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/Register.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/Register.cshtml @@ -8,7 +8,7 @@

Create a new account.


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml index 343fcd8d33..c815424623 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/ResetPassword.cshtml @@ -8,7 +8,7 @@

Reset your password.


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/UseRecoveryCode.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/UseRecoveryCode.cshtml index 7c74d72a23..dd52938373 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/UseRecoveryCode.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/UseRecoveryCode.cshtml @@ -6,7 +6,7 @@

@ViewData["Title"].

-
+

@ViewData["Status"]


diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyAuthenticatorCode.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyAuthenticatorCode.cshtml index f675dd1535..04ead74dbb 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyAuthenticatorCode.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyAuthenticatorCode.cshtml @@ -6,7 +6,7 @@

@ViewData["Title"].

-
+

@ViewData["Status"]


diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml index 330a659ca7..4f15eda730 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Account/VerifyCode.cshtml @@ -6,7 +6,7 @@

@ViewData["Title"].

-
+

@ViewData["Status"]

diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml index 40885f3832..679dcb0a05 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/AddPhoneNumber.cshtml @@ -7,7 +7,7 @@

Add a phone number.


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml index a8d076821b..4d3b38c13c 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/ChangePassword.cshtml @@ -8,7 +8,7 @@

Change Password Form


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml index d1a1b77a44..ccd5781882 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/SetPassword.cshtml @@ -11,7 +11,7 @@

Set your password


-
+
diff --git a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml index 076c20562c..6c4718a6f7 100644 --- a/src/Identity/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml +++ b/src/Identity/samples/IdentitySample.Mvc/Views/Manage/VerifyPhoneNumber.cshtml @@ -10,7 +10,7 @@

Add a phone number.

@ViewData["Status"]

-
+
diff --git a/src/Identity/test/Identity.FunctionalTests/LoginTests.cs b/src/Identity/test/Identity.FunctionalTests/LoginTests.cs index 8a5125495a..bb7529a3a6 100644 --- a/src/Identity/test/Identity.FunctionalTests/LoginTests.cs +++ b/src/Identity/test/Identity.FunctionalTests/LoginTests.cs @@ -230,6 +230,33 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests await UserStories.LoginExistingUserAsync(newClient, userName, password); } + [Fact] + public async Task CanResendConfirmingEmail() + { + // Arrange + var emailSender = new ContosoEmailSender(); + void ConfigureTestServices(IServiceCollection services) => services + .SetupTestEmailSender(emailSender) + .SetupEmailRequired(); + + var server = ServerFactory.WithWebHostBuilder(whb => whb.ConfigureServices(ConfigureTestServices)); + + var client = server.CreateClient(); + var newClient = server.CreateClient(); + + var userName = $"{Guid.NewGuid()}@example.com"; + var password = $"!Test.Password1$"; + + var loggedIn = await UserStories.RegisterNewUserAsync(client, userName, password); + + // Act & Assert + // Use a new client to simulate a new browser session. + await UserStories.ResendConfirmEmailAsync(server.CreateClient(), userName); + Assert.Equal(2, emailSender.SentEmails.Count); + var email = emailSender.SentEmails.Last(); + await UserStories.ConfirmEmailAsync(email, newClient); + } + [Fact] public async Task CanLogInAfterConfirmingEmail_WithGlobalAuthorizeFilter() { diff --git a/src/Identity/test/Identity.FunctionalTests/Microsoft.AspNetCore.Identity.FunctionalTests.csproj b/src/Identity/test/Identity.FunctionalTests/Microsoft.AspNetCore.Identity.FunctionalTests.csproj index a69bb12e4a..5e0e94e218 100644 --- a/src/Identity/test/Identity.FunctionalTests/Microsoft.AspNetCore.Identity.FunctionalTests.csproj +++ b/src/Identity/test/Identity.FunctionalTests/Microsoft.AspNetCore.Identity.FunctionalTests.csproj @@ -2,7 +2,7 @@ $(DefaultNetCoreTargetFramework) - + true diff --git a/src/Identity/test/Identity.FunctionalTests/Pages/Account/Login.cs b/src/Identity/test/Identity.FunctionalTests/Pages/Account/Login.cs index 7db145000f..6960ac8964 100644 --- a/src/Identity/test/Identity.FunctionalTests/Pages/Account/Login.cs +++ b/src/Identity/test/Identity.FunctionalTests/Pages/Account/Login.cs @@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account { private readonly IHtmlFormElement _loginForm; private readonly IHtmlAnchorElement _forgotPasswordLink; + private readonly IHtmlAnchorElement _reconfirmLink; private readonly IHtmlFormElement _externalLoginForm; private readonly IHtmlElement _contosoButton; private readonly IHtmlElement _loginButton; @@ -26,6 +27,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account _loginForm = HtmlAssert.HasForm("#account", login); _loginButton = HtmlAssert.HasElement("#login-submit", login); _forgotPasswordLink = HtmlAssert.HasLink("#forgot-password", login); + _reconfirmLink = HtmlAssert.HasLink("#resend-confirmation", login); if (Context.ContosoLoginEnabled) { _externalLoginForm = HtmlAssert.HasForm("#external-account", login); @@ -52,6 +54,14 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account return new ForgotPassword(Client, forgotPassword, Context); } + public async Task ClickReconfirmEmailLinkAsync() + { + var response = await Client.GetAsync(_reconfirmLink.Href); + var forgotPassword = await ResponseAssert.IsHtmlDocumentAsync(response); + + return new ResendEmailConfirmation(Client, forgotPassword, Context); + } + public async Task LoginValidUserAsync(string userName, string password) { var loggedIn = await SendLoginForm(userName, password); diff --git a/src/Identity/test/Identity.FunctionalTests/Pages/Account/ResendEmailConfirmation.cs b/src/Identity/test/Identity.FunctionalTests/Pages/Account/ResendEmailConfirmation.cs new file mode 100644 index 0000000000..d41cb142d8 --- /dev/null +++ b/src/Identity/test/Identity.FunctionalTests/Pages/Account/ResendEmailConfirmation.cs @@ -0,0 +1,26 @@ +// 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.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using AngleSharp.Dom.Html; + +namespace Microsoft.AspNetCore.Identity.FunctionalTests.Account +{ + public class ResendEmailConfirmation : DefaultUIPage + { + private readonly IHtmlFormElement _resendForm; + + public ResendEmailConfirmation(HttpClient client, IHtmlDocument document, DefaultUIContext context) : base(client, document, context) + { + _resendForm = HtmlAssert.HasForm(document); + } + + public Task ResendAsync(string email) + => Client.SendAsync(_resendForm, new Dictionary + { + ["Input_Email"] = email + }); + } +} diff --git a/src/Identity/test/Identity.FunctionalTests/RegistrationTests.cs b/src/Identity/test/Identity.FunctionalTests/RegistrationTests.cs index 760b36088f..a07404d666 100644 --- a/src/Identity/test/Identity.FunctionalTests/RegistrationTests.cs +++ b/src/Identity/test/Identity.FunctionalTests/RegistrationTests.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using Identity.DefaultUI.WebSite; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; @@ -155,9 +156,10 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests public async Task CanRegisterWithASocialLoginProviderFromLoginWithConfirmationAndRealEmailSender() { // Arrange + var emailSender = new ContosoEmailSender(); void ConfigureTestServices(IServiceCollection services) { - services.AddSingleton(); + services.SetupTestEmailSender(emailSender); services .Configure(o => o.SignIn.RequireConfirmedAccount = true) .SetupTestThirdPartyLogin(); @@ -173,6 +175,7 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests // Act & Assert await UserStories.RegisterNewUserWithSocialLoginWithConfirmationAsync(client, userName, email, hasRealEmailSender: true); + Assert.Single(emailSender.SentEmails); } [Fact] diff --git a/src/Identity/test/Identity.FunctionalTests/UserStories.cs b/src/Identity/test/Identity.FunctionalTests/UserStories.cs index 2cc1cde822..2610139fe0 100644 --- a/src/Identity/test/Identity.FunctionalTests/UserStories.cs +++ b/src/Identity/test/Identity.FunctionalTests/UserStories.cs @@ -194,6 +194,16 @@ namespace Microsoft.AspNetCore.Identity.FunctionalTests .WithConfirmedEmail()); } + internal static async Task ResendConfirmEmailAsync(HttpClient client, string email) + { + var index = await Index.CreateAsync(client); + var login = await index.ClickLoginLinkAsync(); + var reconfirm = await login.ClickReconfirmEmailLinkAsync(); + var response = await reconfirm.ResendAsync(email); + ResponseAssert.IsOK(response); + Assert.Contains("Verification email sent.", await response.Content.ReadAsStringAsync()); + } + internal static async Task ForgotPasswordAsync(HttpClient client, string userName) { var index = await Index.CreateAsync(client); diff --git a/src/Identity/test/Identity.Test/IdentityBuilderTest.cs b/src/Identity/test/Identity.Test/IdentityBuilderTest.cs index 492727ef04..9d5b4c88de 100644 --- a/src/Identity/test/Identity.Test/IdentityBuilderTest.cs +++ b/src/Identity/test/Identity.Test/IdentityBuilderTest.cs @@ -80,6 +80,22 @@ namespace Microsoft.AspNetCore.Identity.Test Assert.NotNull(thingy); } + [Fact] + public void CanOverrideUserConfirmation() + { + var services = new ServiceCollection() + .AddLogging() + .AddSingleton(new ConfigurationBuilder().Build()); + services.AddIdentity() + .AddClaimsPrincipalFactory() + .AddUserConfirmation() + .AddUserManager() + .AddUserStore() + .AddRoleStore(); + var thingy = services.BuildServiceProvider().GetRequiredService>() as MyUserConfirmation; + Assert.NotNull(thingy); + } + [Fact] public void CanOverrideRoleValidator() { @@ -356,5 +372,9 @@ namespace Microsoft.AspNetCore.Identity.Test } } + + private class MyUserConfirmation : DefaultUserConfirmation + { + } } } diff --git a/src/Identity/testassets/Identity.DefaultUI.WebSite/Pages/Contoso/Login.cshtml b/src/Identity/testassets/Identity.DefaultUI.WebSite/Pages/Contoso/Login.cshtml index 91d36c62b0..0bcefd7555 100644 --- a/src/Identity/testassets/Identity.DefaultUI.WebSite/Pages/Contoso/Login.cshtml +++ b/src/Identity/testassets/Identity.DefaultUI.WebSite/Pages/Contoso/Login.cshtml @@ -10,7 +10,7 @@
-
+
diff --git a/src/Installers/Windows/SharedFramework/SharedFramework.wixproj b/src/Installers/Windows/SharedFramework/SharedFramework.wixproj index 4476040486..ab12fc945f 100644 --- a/src/Installers/Windows/SharedFramework/SharedFramework.wixproj +++ b/src/Installers/Windows/SharedFramework/SharedFramework.wixproj @@ -58,7 +58,7 @@ - + $(InstallersOutputPath) diff --git a/src/Installers/Windows/SharedFramework/SharedFrameworkPackage.nuspec b/src/Installers/Windows/SharedFramework/SharedFrameworkPackage.nuspec index 29145c1165..946588c887 100644 --- a/src/Installers/Windows/SharedFramework/SharedFrameworkPackage.nuspec +++ b/src/Installers/Windows/SharedFramework/SharedFrameworkPackage.nuspec @@ -7,7 +7,7 @@ Microsoft Microsoft https://www.microsoft.com/net/dotnet_library_license.htm - https://github.com/aspnet/aspnetcore + https://github.com/dotnet/aspnetcore true $MAJOR$.$MINOR$ ASP.NET Core TargetingPack ($ARCH$) Windows Installer MSI as a .nupkg for internal Visual Studio build consumption © Microsoft Corporation. All rights reserved. diff --git a/src/Installers/Windows/TargetingPack/TargetingPack.wixproj b/src/Installers/Windows/TargetingPack/TargetingPack.wixproj index 984035c9d6..8b47c156e3 100644 --- a/src/Installers/Windows/TargetingPack/TargetingPack.wixproj +++ b/src/Installers/Windows/TargetingPack/TargetingPack.wixproj @@ -57,7 +57,7 @@ - + $(InstallersOutputPath) diff --git a/src/Installers/Windows/TargetingPack/TargetingPackPackage.nuspec b/src/Installers/Windows/TargetingPack/TargetingPackPackage.nuspec index 0c15816136..f814533970 100644 --- a/src/Installers/Windows/TargetingPack/TargetingPackPackage.nuspec +++ b/src/Installers/Windows/TargetingPack/TargetingPackPackage.nuspec @@ -7,7 +7,7 @@ Microsoft Microsoft https://www.microsoft.com/net/dotnet_library_license.htm - https://github.com/aspnet/aspnetcore + https://github.com/dotnet/aspnetcore true $MAJOR$.$MINOR$ ASP.NET Core TargetingPack ($ARCH$) Windows Installer MSI as a .nupkg for internal Visual Studio build consumption © Microsoft Corporation. All rights reserved. diff --git a/src/Middleware/CORS/ref/Microsoft.AspNetCore.Cors.netcoreapp.cs b/src/Middleware/CORS/ref/Microsoft.AspNetCore.Cors.netcoreapp.cs index 9baec2b608..65ec6b11b6 100644 --- a/src/Middleware/CORS/ref/Microsoft.AspNetCore.Cors.netcoreapp.cs +++ b/src/Middleware/CORS/ref/Microsoft.AspNetCore.Cors.netcoreapp.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Cors public partial class CorsPolicyMetadata : Microsoft.AspNetCore.Cors.Infrastructure.ICorsMetadata, Microsoft.AspNetCore.Cors.Infrastructure.ICorsPolicyMetadata { public CorsPolicyMetadata(Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy policy) { } - public Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)] public partial class DisableCorsAttribute : System.Attribute, Microsoft.AspNetCore.Cors.Infrastructure.ICorsMetadata, Microsoft.AspNetCore.Cors.Infrastructure.IDisableCorsAttribute @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Cors { public EnableCorsAttribute() { } public EnableCorsAttribute(string policyName) { } - public string PolicyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PolicyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Cors.Infrastructure @@ -74,13 +74,13 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure public bool AllowAnyHeader { get { throw null; } } public bool AllowAnyMethod { get { throw null; } } public bool AllowAnyOrigin { get { throw null; } } - public System.Collections.Generic.IList ExposedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Func IsOriginAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Methods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Origins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ExposedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Func IsOriginAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Methods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Origins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.TimeSpan? PreflightMaxAge { get { throw null; } set { } } - public bool SupportsCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SupportsCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string ToString() { throw null; } } public partial class CorsPolicyBuilder @@ -104,15 +104,15 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure public partial class CorsResult { public CorsResult() { } - public System.Collections.Generic.IList AllowedExposedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList AllowedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList AllowedMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string AllowedOrigin { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsOriginAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsPreflightRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AllowedExposedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList AllowedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList AllowedMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string AllowedOrigin { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsOriginAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsPreflightRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.TimeSpan? PreflightMaxAge { get { throw null; } set { } } - public bool SupportsCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool VaryByOrigin { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SupportsCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool VaryByOrigin { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string ToString() { throw null; } } public partial class CorsService : Microsoft.AspNetCore.Cors.Infrastructure.ICorsService diff --git a/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs b/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs index 02e5c7a0d1..2eece1f8e1 100644 --- a/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs +++ b/src/Middleware/CORS/src/Infrastructure/CorsMiddleware.cs @@ -143,10 +143,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure if (corsMetadata is IDisableCorsAttribute) { - var isOptionsRequest = string.Equals( - context.Request.Method, - CorsConstants.PreflightHttpMethod, - StringComparison.OrdinalIgnoreCase); + var isOptionsRequest = HttpMethods.IsOptions(context.Request.Method); var isCorsPreflightRequest = isOptionsRequest && context.Request.Headers.ContainsKey(CorsConstants.AccessControlRequestMethod); @@ -184,7 +181,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure return InvokeCoreAwaited(context, policyTask); } - corsPolicy = policyTask.GetAwaiter().GetResult(); + corsPolicy = policyTask.Result; } return EvaluateAndApplyPolicy(context, corsPolicy); diff --git a/src/Middleware/CORS/src/Infrastructure/CorsPolicy.cs b/src/Middleware/CORS/src/Infrastructure/CorsPolicy.cs index f541863c69..8c7529d30e 100644 --- a/src/Middleware/CORS/src/Infrastructure/CorsPolicy.cs +++ b/src/Middleware/CORS/src/Infrastructure/CorsPolicy.cs @@ -142,16 +142,16 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure builder.Append(", SupportsCredentials: "); builder.Append(SupportsCredentials); builder.Append(", Origins: {"); - builder.Append(string.Join(",", Origins)); + builder.AppendJoin(",", Origins); builder.Append("}"); builder.Append(", Methods: {"); - builder.Append(string.Join(",", Methods)); + builder.AppendJoin(",", Methods); builder.Append("}"); builder.Append(", Headers: {"); - builder.Append(string.Join(",", Headers)); + builder.AppendJoin(",", Headers); builder.Append("}"); builder.Append(", ExposedHeaders: {"); - builder.Append(string.Join(",", ExposedHeaders)); + builder.AppendJoin(",", ExposedHeaders); builder.Append("}"); return builder.ToString(); } @@ -161,4 +161,4 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure return Origins.Contains(origin, StringComparer.Ordinal); } } -} \ No newline at end of file +} diff --git a/src/Middleware/CORS/src/Infrastructure/CorsResult.cs b/src/Middleware/CORS/src/Infrastructure/CorsResult.cs index 558a99a31d..16cf9bb66a 100644 --- a/src/Middleware/CORS/src/Infrastructure/CorsResult.cs +++ b/src/Middleware/CORS/src/Infrastructure/CorsResult.cs @@ -91,15 +91,15 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure builder.Append(", AllowOrigin: "); builder.Append(AllowedOrigin); builder.Append(", AllowExposedHeaders: {"); - builder.Append(string.Join(",", AllowedExposedHeaders)); + builder.AppendJoin(",", AllowedExposedHeaders); builder.Append("}"); builder.Append(", AllowHeaders: {"); - builder.Append(string.Join(",", AllowedHeaders)); + builder.AppendJoin(",", AllowedHeaders); builder.Append("}"); builder.Append(", AllowMethods: {"); - builder.Append(string.Join(",", AllowedMethods)); + builder.AppendJoin(",", AllowedMethods); builder.Append("}"); return builder.ToString(); } } -} \ No newline at end of file +} diff --git a/src/Middleware/CORS/src/Infrastructure/CorsService.cs b/src/Middleware/CORS/src/Infrastructure/CorsService.cs index 7552d81574..8ed5ca318c 100644 --- a/src/Middleware/CORS/src/Infrastructure/CorsService.cs +++ b/src/Middleware/CORS/src/Infrastructure/CorsService.cs @@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure var requestHeaders = context.Request.Headers; var origin = requestHeaders[CorsConstants.Origin]; - var isOptionsRequest = string.Equals(context.Request.Method, CorsConstants.PreflightHttpMethod, StringComparison.OrdinalIgnoreCase); + var isOptionsRequest = HttpMethods.IsOptions(context.Request.Method); var isPreflightRequest = isOptionsRequest && requestHeaders.ContainsKey(CorsConstants.AccessControlRequestMethod); if (isOptionsRequest && !isPreflightRequest) diff --git a/src/Middleware/ConcurrencyLimiter/ref/Microsoft.AspNetCore.ConcurrencyLimiter.netcoreapp.cs b/src/Middleware/ConcurrencyLimiter/ref/Microsoft.AspNetCore.ConcurrencyLimiter.netcoreapp.cs index 6c2e1cf26d..e96ad66457 100644 --- a/src/Middleware/ConcurrencyLimiter/ref/Microsoft.AspNetCore.ConcurrencyLimiter.netcoreapp.cs +++ b/src/Middleware/ConcurrencyLimiter/ref/Microsoft.AspNetCore.ConcurrencyLimiter.netcoreapp.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter public partial class ConcurrencyLimiterOptions { public ConcurrencyLimiterOptions() { } - public Microsoft.AspNetCore.Http.RequestDelegate OnRejected { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.RequestDelegate OnRejected { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IQueuePolicy { @@ -29,8 +29,8 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter public partial class QueuePolicyOptions { public QueuePolicyOptions() { } - public int MaxConcurrentRequests { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RequestQueueLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int MaxConcurrentRequests { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RequestQueueLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs index aec06f6eb6..08d6338df2 100644 --- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs +++ b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs @@ -10,31 +10,35 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter { internal class QueuePolicy : IQueuePolicy, IDisposable { - private readonly int _maxConcurrentRequests; - private readonly int _requestQueueLimit; + private readonly int _maxTotalRequest; private readonly SemaphoreSlim _serverSemaphore; private object _totalRequestsLock = new object(); + public int TotalRequests { get; private set; } public QueuePolicy(IOptions options) { - _maxConcurrentRequests = options.Value.MaxConcurrentRequests; - if (_maxConcurrentRequests <= 0) + var queuePolicyOptions = options.Value; + + var maxConcurrentRequests = queuePolicyOptions.MaxConcurrentRequests; + if (maxConcurrentRequests <= 0) { - throw new ArgumentException(nameof(_maxConcurrentRequests), "MaxConcurrentRequests must be a positive integer."); + throw new ArgumentException(nameof(maxConcurrentRequests), "MaxConcurrentRequests must be a positive integer."); } - _requestQueueLimit = options.Value.RequestQueueLimit; - if (_requestQueueLimit < 0) + var requestQueueLimit = queuePolicyOptions.RequestQueueLimit; + if (requestQueueLimit < 0) { - throw new ArgumentException(nameof(_requestQueueLimit), "The RequestQueueLimit cannot be a negative number."); + throw new ArgumentException(nameof(requestQueueLimit), "The RequestQueueLimit cannot be a negative number."); } - _serverSemaphore = new SemaphoreSlim(_maxConcurrentRequests); + _serverSemaphore = new SemaphoreSlim(maxConcurrentRequests); + + _maxTotalRequest = maxConcurrentRequests + requestQueueLimit; } - public async ValueTask TryEnterAsync() + public ValueTask TryEnterAsync() { // a return value of 'false' indicates that the request is rejected // a return value of 'true' indicates that the request may proceed @@ -42,17 +46,21 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter lock (_totalRequestsLock) { - if (TotalRequests >= _requestQueueLimit + _maxConcurrentRequests) + if (TotalRequests >= _maxTotalRequest) { - return false; + return new ValueTask(false); } TotalRequests++; } - await _serverSemaphore.WaitAsync(); + Task task = _serverSemaphore.WaitAsync(); + if (task.IsCompletedSuccessfully) + { + return new ValueTask(true); + } - return true; + return SemaphoreAwaited(task); } public void OnExit() @@ -69,5 +77,12 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter { _serverSemaphore.Dispose(); } + + private async ValueTask SemaphoreAwaited(Task task) + { + await task; + + return true; + } } } diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs index 557aedfac4..5dcd5927d1 100644 --- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs +++ b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs @@ -21,8 +21,6 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter private readonly object _bufferLock = new Object(); - private readonly static ValueTask _trueTask = new ValueTask(true); - private int _freeServerSpots; public StackPolicy(IOptions options) @@ -40,7 +38,7 @@ namespace Microsoft.AspNetCore.ConcurrencyLimiter if (_freeServerSpots > 0) { _freeServerSpots--; - return _trueTask; + return new ValueTask(true); } // if queue is full, cancel oldest request diff --git a/src/Middleware/Diagnostics.Abstractions/ref/Microsoft.AspNetCore.Diagnostics.Abstractions.netcoreapp.cs b/src/Middleware/Diagnostics.Abstractions/ref/Microsoft.AspNetCore.Diagnostics.Abstractions.netcoreapp.cs index 9d8c6215ca..024b7bb9c9 100644 --- a/src/Middleware/Diagnostics.Abstractions/ref/Microsoft.AspNetCore.Diagnostics.Abstractions.netcoreapp.cs +++ b/src/Middleware/Diagnostics.Abstractions/ref/Microsoft.AspNetCore.Diagnostics.Abstractions.netcoreapp.cs @@ -7,28 +7,28 @@ namespace Microsoft.AspNetCore.Diagnostics { public CompilationFailure(string sourceFilePath, string sourceFileContent, string compiledContent, System.Collections.Generic.IEnumerable messages) { } public CompilationFailure(string sourceFilePath, string sourceFileContent, string compiledContent, System.Collections.Generic.IEnumerable messages, string failureSummary) { } - public string CompiledContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string FailureSummary { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IEnumerable Messages { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string SourceFileContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string SourceFilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string CompiledContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string FailureSummary { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IEnumerable Messages { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string SourceFileContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string SourceFilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class DiagnosticMessage { public DiagnosticMessage(string message, string formattedMessage, string filePath, int startLine, int startColumn, int endLine, int endColumn) { } - public int EndColumn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int EndLine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string FormattedMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string SourceFilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int StartColumn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int StartLine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int EndColumn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int EndLine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string FormattedMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string SourceFilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int StartColumn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int StartLine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ErrorContext { public ErrorContext(Microsoft.AspNetCore.Http.HttpContext httpContext, System.Exception exception) { } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface ICompilationException { diff --git a/src/Middleware/Diagnostics.EntityFrameworkCore/ref/Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.netcoreapp.cs b/src/Middleware/Diagnostics.EntityFrameworkCore/ref/Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.netcoreapp.cs index 04d8f01552..e358254af3 100644 --- a/src/Middleware/Diagnostics.EntityFrameworkCore/ref/Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.netcoreapp.cs +++ b/src/Middleware/Diagnostics.EntityFrameworkCore/ref/Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.netcoreapp.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Builder public partial class DatabaseErrorPageOptions { public DatabaseErrorPageOptions() { } - public virtual Microsoft.AspNetCore.Http.PathString MigrationsEndPointPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.AspNetCore.Http.PathString MigrationsEndPointPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class MigrationsEndPointExtensions { @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Builder { public static Microsoft.AspNetCore.Http.PathString DefaultPath; public MigrationsEndPointOptions() { } - public virtual Microsoft.AspNetCore.Http.PathString Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.AspNetCore.Http.PathString Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore diff --git a/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseErrorPageMiddleware.cs b/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseErrorPageMiddleware.cs index 26db9dcb22..ac2e913c24 100644 --- a/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseErrorPageMiddleware.cs +++ b/src/Middleware/Diagnostics.EntityFrameworkCore/src/DatabaseErrorPageMiddleware.cs @@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore : context.Database.GetMigrations()) .ToArray(); - if (pendingModelChanges || pendingMigrations.Any()) + if (pendingModelChanges || pendingMigrations.Length > 0) { var page = new DatabaseErrorPage { diff --git a/src/Middleware/Diagnostics/ref/Microsoft.AspNetCore.Diagnostics.netcoreapp.cs b/src/Middleware/Diagnostics/ref/Microsoft.AspNetCore.Diagnostics.netcoreapp.cs index daf4d6edeb..6d400fb3f4 100644 --- a/src/Middleware/Diagnostics/ref/Microsoft.AspNetCore.Diagnostics.netcoreapp.cs +++ b/src/Middleware/Diagnostics/ref/Microsoft.AspNetCore.Diagnostics.netcoreapp.cs @@ -11,8 +11,8 @@ namespace Microsoft.AspNetCore.Builder public partial class DeveloperExceptionPageOptions { public DeveloperExceptionPageOptions() { } - public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int SourceCodeLineCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int SourceCodeLineCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class ExceptionHandlerExtensions { @@ -24,8 +24,8 @@ namespace Microsoft.AspNetCore.Builder public partial class ExceptionHandlerOptions { public ExceptionHandlerOptions() { } - public Microsoft.AspNetCore.Http.RequestDelegate ExceptionHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString ExceptionHandlingPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.RequestDelegate ExceptionHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString ExceptionHandlingPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class StatusCodePagesExtensions { @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Builder public partial class StatusCodePagesOptions { public StatusCodePagesOptions() { } - public System.Func HandleAsync { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func HandleAsync { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class WelcomePageExtensions { @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Builder public partial class WelcomePageOptions { public WelcomePageOptions() { } - public Microsoft.AspNetCore.Http.PathString Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.PathString Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Diagnostics @@ -66,8 +66,8 @@ namespace Microsoft.AspNetCore.Diagnostics public partial class ExceptionHandlerFeature : Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature, Microsoft.AspNetCore.Diagnostics.IExceptionHandlerPathFeature { public ExceptionHandlerFeature() { } - public System.Exception Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ExceptionHandlerMiddleware { @@ -77,14 +77,14 @@ namespace Microsoft.AspNetCore.Diagnostics public partial class StatusCodeContext { public StatusCodeContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Builder.StatusCodePagesOptions options, Microsoft.AspNetCore.Http.RequestDelegate next) { } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.RequestDelegate Next { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Builder.StatusCodePagesOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.RequestDelegate Next { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Builder.StatusCodePagesOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class StatusCodePagesFeature : Microsoft.AspNetCore.Diagnostics.IStatusCodePagesFeature { public StatusCodePagesFeature() { } - public bool Enabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Enabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class StatusCodePagesMiddleware { @@ -95,9 +95,9 @@ namespace Microsoft.AspNetCore.Diagnostics public partial class StatusCodeReExecuteFeature : Microsoft.AspNetCore.Diagnostics.IStatusCodeReExecuteFeature { public StatusCodeReExecuteFeature() { } - public string OriginalPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string OriginalPathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string OriginalQueryString { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string OriginalPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string OriginalPathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string OriginalQueryString { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class WelcomePageMiddleware { diff --git a/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddleware.cs b/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddleware.cs index c503194d6c..25684d0dd7 100644 --- a/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddleware.cs +++ b/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddleware.cs @@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Diagnostics _logger = loggerFactory.CreateLogger(); _fileProvider = _options.FileProvider ?? hostingEnvironment.ContentRootFileProvider; _diagnosticSource = diagnosticSource; - _exceptionDetailsProvider = new ExceptionDetailsProvider(_fileProvider, _options.SourceCodeLineCount); + _exceptionDetailsProvider = new ExceptionDetailsProvider(_fileProvider, _logger, _options.SourceCodeLineCount); _exceptionHandler = DisplayException; foreach (var filter in filters.Reverse()) diff --git a/src/Middleware/Diagnostics/src/DeveloperExceptionPage/Views/ErrorPage.css b/src/Middleware/Diagnostics/src/DeveloperExceptionPage/Views/ErrorPage.css index 54e66c97af..8c60d047a5 100644 --- a/src/Middleware/Diagnostics/src/DeveloperExceptionPage/Views/ErrorPage.css +++ b/src/Middleware/Diagnostics/src/DeveloperExceptionPage/Views/ErrorPage.css @@ -96,6 +96,12 @@ body .location { background-color: #fbfbfb; } +#stackpage .frame .source .highlight { + border-left: 3px solid red; + margin-left: -3px; + font-weight: bold; +} + #stackpage .frame .source .highlight li span { color: #FF0000; } diff --git a/src/Middleware/Diagnostics/src/README.md b/src/Middleware/Diagnostics/src/README.md index b3e72bdd68..07e6ca9a57 100644 --- a/src/Middleware/Diagnostics/src/README.md +++ b/src/Middleware/Diagnostics/src/README.md @@ -3,7 +3,7 @@ ASP.NET Core Diagnostics ## Development -Diagnostics middleware like `DeveloperExceptionPage` uses compiled Razor views. After updating the `*.cshtml` file you must run the [RazorPageGenerator](https://github.com/aspnet/AspNetCore-Tooling/tree/master/src/Razor/src/RazorPageGenerator) tool to generate an updated compiled Razor view. +Diagnostics middleware like `DeveloperExceptionPage` uses compiled Razor views. After updating the `*.cshtml` file you must run the [RazorPageGenerator](https://github.com/dotnet/aspnetcore-tooling/tree/master/src/Razor/src/RazorPageGenerator) tool to generate an updated compiled Razor view. Run the following command in `AspNetCore-Tooling\src\Razor\src\RazorPageGenerator`: diff --git a/src/Middleware/Diagnostics/test/UnitTests/ExceptionDetailsProviderTest.cs b/src/Middleware/Diagnostics/test/UnitTests/ExceptionDetailsProviderTest.cs index bda7bde74d..6ae9b91e2c 100644 --- a/src/Middleware/Diagnostics/test/UnitTests/ExceptionDetailsProviderTest.cs +++ b/src/Middleware/Diagnostics/test/UnitTests/ExceptionDetailsProviderTest.cs @@ -66,7 +66,7 @@ namespace Microsoft.Extensions.Internal using (var provider = new PhysicalFileProvider(rootPath)) { // Act - var exceptionDetailProvider = new ExceptionDetailsProvider(provider, sourceCodeLineCount: 6); + var exceptionDetailProvider = new ExceptionDetailsProvider(provider, logger: null, sourceCodeLineCount: 6); var stackFrame = exceptionDetailProvider.GetStackFrameSourceCodeInfo( "func1", absoluteFilePath, @@ -90,7 +90,7 @@ namespace Microsoft.Extensions.Internal using (var provider = new PhysicalFileProvider(rootPath)) { // Act - var exceptionDetailProvider = new ExceptionDetailsProvider(provider, sourceCodeLineCount: 6); + var exceptionDetailProvider = new ExceptionDetailsProvider(provider, logger: null, sourceCodeLineCount: 6); var stackFrame = exceptionDetailProvider.GetStackFrameSourceCodeInfo( "func1", relativePath, @@ -116,7 +116,7 @@ namespace Microsoft.Extensions.Internal baseNamespace: $"{typeof(ExceptionDetailsProviderTest).GetTypeInfo().Assembly.GetName().Name}.Resources"); // Act - var exceptionDetailProvider = new ExceptionDetailsProvider(provider, sourceCodeLineCount: 6); + var exceptionDetailProvider = new ExceptionDetailsProvider(provider, logger: null, sourceCodeLineCount: 6); var stackFrame = exceptionDetailProvider.GetStackFrameSourceCodeInfo( "func1", relativePath, @@ -259,7 +259,8 @@ namespace Microsoft.Extensions.Internal // Act var exceptionDetailProvider = new ExceptionDetailsProvider( new PhysicalFileProvider(Directory.GetCurrentDirectory()), - sourceCodeLineCount: 6); + logger: null, + sourceCodeLineCount: 6); exceptionDetailProvider.ReadFrameContent( stackFrame, diff --git a/src/Middleware/HeaderPropagation/ref/Microsoft.AspNetCore.HeaderPropagation.netcoreapp.cs b/src/Middleware/HeaderPropagation/ref/Microsoft.AspNetCore.HeaderPropagation.netcoreapp.cs index 887719c624..72f8f37c2e 100644 --- a/src/Middleware/HeaderPropagation/ref/Microsoft.AspNetCore.HeaderPropagation.netcoreapp.cs +++ b/src/Middleware/HeaderPropagation/ref/Microsoft.AspNetCore.HeaderPropagation.netcoreapp.cs @@ -14,17 +14,18 @@ namespace Microsoft.AspNetCore.HeaderPropagation public readonly partial struct HeaderPropagationContext { private readonly object _dummy; + private readonly int _dummyPrimitive; public HeaderPropagationContext(Microsoft.AspNetCore.Http.HttpContext httpContext, string headerName, Microsoft.Extensions.Primitives.StringValues headerValue) { throw null; } - public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.Primitives.StringValues HeaderValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.Primitives.StringValues HeaderValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class HeaderPropagationEntry { public HeaderPropagationEntry(string inboundHeaderName, string capturedHeaderName, System.Func valueFilter) { } - public string CapturedHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string InboundHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Func ValueFilter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string CapturedHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string InboundHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Func ValueFilter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class HeaderPropagationEntryCollection : System.Collections.ObjectModel.Collection { @@ -42,8 +43,8 @@ namespace Microsoft.AspNetCore.HeaderPropagation public partial class HeaderPropagationMessageHandlerEntry { public HeaderPropagationMessageHandlerEntry(string capturedHeaderName, string outboundHeaderName) { } - public string CapturedHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string OutboundHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string CapturedHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string OutboundHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class HeaderPropagationMessageHandlerEntryCollection : System.Collections.ObjectModel.Collection { @@ -54,7 +55,7 @@ namespace Microsoft.AspNetCore.HeaderPropagation public partial class HeaderPropagationMessageHandlerOptions { public HeaderPropagationMessageHandlerOptions() { } - public Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationMessageHandlerEntryCollection Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationMessageHandlerEntryCollection Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HeaderPropagationMiddleware { @@ -64,7 +65,7 @@ namespace Microsoft.AspNetCore.HeaderPropagation public partial class HeaderPropagationOptions { public HeaderPropagationOptions() { } - public Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationEntryCollection Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationEntryCollection Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HeaderPropagationValues { diff --git a/src/Middleware/HealthChecks.EntityFrameworkCore/src/DbContextHealthCheck.cs b/src/Middleware/HealthChecks.EntityFrameworkCore/src/DbContextHealthCheck.cs index 7fa998f296..6481bd29d3 100644 --- a/src/Middleware/HealthChecks.EntityFrameworkCore/src/DbContextHealthCheck.cs +++ b/src/Middleware/HealthChecks.EntityFrameworkCore/src/DbContextHealthCheck.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -49,8 +49,8 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks { return HealthCheckResult.Healthy(); } - - return HealthCheckResult.Unhealthy(); + + return new HealthCheckResult(context.Registration.FailureStatus); } } } diff --git a/src/Middleware/HealthChecks.EntityFrameworkCore/test/DbContextHealthCheckTest.cs b/src/Middleware/HealthChecks.EntityFrameworkCore/test/DbContextHealthCheckTest.cs index fe5383c6f5..df22c3361f 100644 --- a/src/Middleware/HealthChecks.EntityFrameworkCore/test/DbContextHealthCheckTest.cs +++ b/src/Middleware/HealthChecks.EntityFrameworkCore/test/DbContextHealthCheckTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -61,7 +61,7 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks } [Fact] - public async Task CheckAsync_CustomTest_Degraded() + public async Task CheckAsync_CustomTestWithDegradedFailureStatusSpecified_Degraded() { // Arrange var services = CreateServices(async (c, ct) => @@ -78,12 +78,12 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks var result = await check.CheckHealthAsync(new HealthCheckContext() { Registration = registration, }); // Assert - Assert.Equal(HealthStatus.Unhealthy, result.Status); + Assert.Equal(HealthStatus.Degraded, result.Status); } } [Fact] - public async Task CheckAsync_CustomTest_Unhealthy() + public async Task CheckAsync_CustomTestWithUnhealthyFailureStatusSpecified_Unhealthy() { // Arrange var services = CreateServices(async (c, ct) => @@ -104,12 +104,34 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks } } + [Fact] + public async Task CheckAsync_CustomTestWithNoFailureStatusSpecified_Unhealthy() + { + // Arrange + var services = CreateServices(async (c, ct) => + { + return 0 < await c.Blogs.CountAsync(); + }, failureStatus: null); + + using (var scope = services.GetRequiredService().CreateScope()) + { + var registration = Assert.Single(services.GetRequiredService>().Value.Registrations); + var check = ActivatorUtilities.CreateInstance>(scope.ServiceProvider); + + // Act + var result = await check.CheckHealthAsync(new HealthCheckContext() { Registration = registration, }); + + // Assert + Assert.Equal(HealthStatus.Unhealthy, result.Status); + } + } + // used to ensure each test uses a unique in-memory database private static int _testDbCounter; private static IServiceProvider CreateServices( Func> testQuery = null, - HealthStatus failureStatus = HealthStatus.Unhealthy) + HealthStatus? failureStatus = HealthStatus.Unhealthy) { var serviceCollection = new ServiceCollection(); serviceCollection.AddDbContext(o => o.UseInMemoryDatabase("Test" + Interlocked.Increment(ref _testDbCounter))); diff --git a/src/Middleware/HealthChecks.EntityFrameworkCore/test/Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests.csproj b/src/Middleware/HealthChecks.EntityFrameworkCore/test/Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests.csproj index 7cd8abe252..4f1c6075fd 100644 --- a/src/Middleware/HealthChecks.EntityFrameworkCore/test/Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests.csproj +++ b/src/Middleware/HealthChecks.EntityFrameworkCore/test/Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore.Tests.csproj @@ -3,6 +3,9 @@ $(DefaultNetCoreTargetFramework) Microsoft.AspNetCore.Diagnostics.HealthChecks + + $(NoWarn);NU1605 diff --git a/src/Middleware/HealthChecks/ref/Microsoft.AspNetCore.Diagnostics.HealthChecks.netcoreapp.cs b/src/Middleware/HealthChecks/ref/Microsoft.AspNetCore.Diagnostics.HealthChecks.netcoreapp.cs index 8433e54f12..a41b1272ed 100644 --- a/src/Middleware/HealthChecks/ref/Microsoft.AspNetCore.Diagnostics.HealthChecks.netcoreapp.cs +++ b/src/Middleware/HealthChecks/ref/Microsoft.AspNetCore.Diagnostics.HealthChecks.netcoreapp.cs @@ -29,9 +29,9 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks public partial class HealthCheckOptions { public HealthCheckOptions() { } - public bool AllowCachingResponses { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func Predicate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func ResponseWriter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowCachingResponses { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func Predicate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func ResponseWriter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.IDictionary ResultStatusCodes { get { throw null; } set { } } } } diff --git a/src/Middleware/HealthChecks/src/HealthCheckMiddleware.cs b/src/Middleware/HealthChecks/src/HealthCheckMiddleware.cs index ba6b870bdc..53726257b0 100644 --- a/src/Middleware/HealthChecks/src/HealthCheckMiddleware.cs +++ b/src/Middleware/HealthChecks/src/HealthCheckMiddleware.cs @@ -85,41 +85,5 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks await _healthCheckOptions.ResponseWriter(httpContext, result); } } - - private static IHealthCheck[] FilterHealthChecks( - IReadOnlyDictionary checks, - ISet names) - { - // If there are no filters then include all checks. - if (names.Count == 0) - { - return checks.Values.ToArray(); - } - - // Keep track of what we don't find so we can report errors. - var notFound = new HashSet(names, StringComparer.OrdinalIgnoreCase); - var matches = new List(); - - foreach (var kvp in checks) - { - if (!notFound.Remove(kvp.Key)) - { - // This check was excluded - continue; - } - - matches.Add(kvp.Value); - } - - if (notFound.Count > 0) - { - var message = - $"The following health checks were not found: '{string.Join(", ", notFound)}'. " + - $"Registered health checks: '{string.Join(", ", checks.Keys)}'."; - throw new InvalidOperationException(message); - } - - return matches.ToArray(); - } } } diff --git a/src/Middleware/HealthChecks/src/HealthCheckOptions.cs b/src/Middleware/HealthChecks/src/HealthCheckOptions.cs index c5ef255662..8d7ea07098 100644 --- a/src/Middleware/HealthChecks/src/HealthCheckOptions.cs +++ b/src/Middleware/HealthChecks/src/HealthCheckOptions.cs @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks private static IDictionary ValidateStatusCodesMapping(IDictionary mapping) { var missingHealthStatus = ((HealthStatus[])Enum.GetValues(typeof(HealthStatus))).Except(mapping.Keys).ToList(); - if (missingHealthStatus.Any()) + if (missingHealthStatus.Count > 0) { var missing = string.Join(", ", missingHealthStatus.Select(status => $"{nameof(HealthStatus)}.{status}")); var message = diff --git a/src/Middleware/HostFiltering/ref/Microsoft.AspNetCore.HostFiltering.netcoreapp.cs b/src/Middleware/HostFiltering/ref/Microsoft.AspNetCore.HostFiltering.netcoreapp.cs index 51bb051429..d201977515 100644 --- a/src/Middleware/HostFiltering/ref/Microsoft.AspNetCore.HostFiltering.netcoreapp.cs +++ b/src/Middleware/HostFiltering/ref/Microsoft.AspNetCore.HostFiltering.netcoreapp.cs @@ -22,8 +22,8 @@ namespace Microsoft.AspNetCore.HostFiltering public partial class HostFilteringOptions { public HostFilteringOptions() { } - public System.Collections.Generic.IList AllowedHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool AllowEmptyHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IncludeFailureMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AllowedHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool AllowEmptyHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IncludeFailureMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Middleware/HttpOverrides/ref/Microsoft.AspNetCore.HttpOverrides.netcoreapp.cs b/src/Middleware/HttpOverrides/ref/Microsoft.AspNetCore.HttpOverrides.netcoreapp.cs index f21794c54b..de66a5e16b 100644 --- a/src/Middleware/HttpOverrides/ref/Microsoft.AspNetCore.HttpOverrides.netcoreapp.cs +++ b/src/Middleware/HttpOverrides/ref/Microsoft.AspNetCore.HttpOverrides.netcoreapp.cs @@ -15,18 +15,18 @@ namespace Microsoft.AspNetCore.Builder public partial class ForwardedHeadersOptions { public ForwardedHeadersOptions() { } - public System.Collections.Generic.IList AllowedHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardedForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders ForwardedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardedHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardedProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? ForwardLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList KnownNetworks { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList KnownProxies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string OriginalForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string OriginalHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string OriginalProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireHeaderSymmetry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AllowedHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardedForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders ForwardedHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardedHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardedProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? ForwardLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList KnownNetworks { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList KnownProxies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string OriginalForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string OriginalHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string OriginalProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireHeaderSymmetry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class HttpMethodOverrideExtensions { @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Builder public partial class HttpMethodOverrideOptions { public HttpMethodOverrideOptions() { } - public string FormFieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FormFieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.HttpOverrides @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.HttpOverrides { public System.Func HeaderConverter; public CertificateForwardingOptions() { } - public string CertificateHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string CertificateHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.FlagsAttribute] public enum ForwardedHeaders @@ -63,12 +63,12 @@ namespace Microsoft.AspNetCore.HttpOverrides } public static partial class ForwardedHeadersDefaults { - public static string XForwardedForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public static string XForwardedHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public static string XForwardedProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public static string XOriginalForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public static string XOriginalHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public static string XOriginalProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public static string XForwardedForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public static string XForwardedHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public static string XForwardedProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public static string XOriginalForHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public static string XOriginalHostHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public static string XOriginalProtoHeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ForwardedHeadersMiddleware { @@ -85,8 +85,8 @@ namespace Microsoft.AspNetCore.HttpOverrides public partial class IPNetwork { public IPNetwork(System.Net.IPAddress prefix, int prefixLength) { } - public System.Net.IPAddress Prefix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int PrefixLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Net.IPAddress Prefix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int PrefixLength { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Contains(System.Net.IPAddress address) { throw null; } } } diff --git a/src/Middleware/HttpOverrides/src/HttpMethodOverrideMiddleware.cs b/src/Middleware/HttpOverrides/src/HttpMethodOverrideMiddleware.cs index 60965e50b1..6fc75b7a36 100644 --- a/src/Middleware/HttpOverrides/src/HttpMethodOverrideMiddleware.cs +++ b/src/Middleware/HttpOverrides/src/HttpMethodOverrideMiddleware.cs @@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.HttpOverrides public async Task Invoke(HttpContext context) { - if (string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsPost(context.Request.Method)) { if (_options.FormFieldName != null) { diff --git a/src/Middleware/HttpsPolicy/ref/Microsoft.AspNetCore.HttpsPolicy.netcoreapp.cs b/src/Middleware/HttpsPolicy/ref/Microsoft.AspNetCore.HttpsPolicy.netcoreapp.cs index dc22bca076..0f54084eef 100644 --- a/src/Middleware/HttpsPolicy/ref/Microsoft.AspNetCore.HttpsPolicy.netcoreapp.cs +++ b/src/Middleware/HttpsPolicy/ref/Microsoft.AspNetCore.HttpsPolicy.netcoreapp.cs @@ -31,10 +31,10 @@ namespace Microsoft.AspNetCore.HttpsPolicy public partial class HstsOptions { public HstsOptions() { } - public System.Collections.Generic.IList ExcludedHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IncludeSubDomains { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Preload { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList ExcludedHosts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IncludeSubDomains { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Preload { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HttpsRedirectionMiddleware { @@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.HttpsPolicy public partial class HttpsRedirectionOptions { public HttpsRedirectionOptions() { } - public int? HttpsPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int RedirectStatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? HttpsPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int RedirectStatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs b/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs index e20e8b8a33..1a67121215 100644 --- a/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs +++ b/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs @@ -13,6 +13,9 @@ using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.HttpsPolicy { + /// + /// Middleware that redirects non-HTTPS requests to an HTTPS URL. + /// public class HttpsRedirectionMiddleware { private const int PortNotFound = -1; @@ -26,7 +29,7 @@ namespace Microsoft.AspNetCore.HttpsPolicy private readonly ILogger _logger; /// - /// Initializes the HttpsRedirectionMiddleware + /// Initializes . /// /// /// @@ -56,13 +59,13 @@ namespace Microsoft.AspNetCore.HttpsPolicy } /// - /// Initializes the HttpsRedirectionMiddleware + /// Initializes . /// /// /// /// /// - /// The + /// public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config, ILoggerFactory loggerFactory, IServerAddressesFeature serverAddressesFeature) : this(next, options, config, loggerFactory) @@ -71,7 +74,7 @@ namespace Microsoft.AspNetCore.HttpsPolicy } /// - /// Invokes the HttpsRedirectionMiddleware + /// Invokes the HttpsRedirectionMiddleware. /// /// /// diff --git a/src/Middleware/HttpsPolicy/src/HttpsRedirectionOptions.cs b/src/Middleware/HttpsPolicy/src/HttpsRedirectionOptions.cs index 07a166c162..0e1c625bd7 100644 --- a/src/Middleware/HttpsPolicy/src/HttpsRedirectionOptions.cs +++ b/src/Middleware/HttpsPolicy/src/HttpsRedirectionOptions.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.HttpsPolicy { /// - /// Options for the HttpsRedirection middleware + /// Options for the HTTPS Redirection Middleware. /// public class HttpsRedirectionOptions { diff --git a/src/Middleware/Localization.Routing/ref/Microsoft.AspNetCore.Localization.Routing.netcoreapp.cs b/src/Middleware/Localization.Routing/ref/Microsoft.AspNetCore.Localization.Routing.netcoreapp.cs index 32ec45d65f..799e047c26 100644 --- a/src/Middleware/Localization.Routing/ref/Microsoft.AspNetCore.Localization.Routing.netcoreapp.cs +++ b/src/Middleware/Localization.Routing/ref/Microsoft.AspNetCore.Localization.Routing.netcoreapp.cs @@ -6,8 +6,8 @@ namespace Microsoft.AspNetCore.Localization.Routing public partial class RouteDataRequestCultureProvider : Microsoft.AspNetCore.Localization.RequestCultureProvider { public RouteDataRequestCultureProvider() { } - public string RouteDataStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UIRouteDataStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RouteDataStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UIRouteDataStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task DetermineProviderCultureResult(Microsoft.AspNetCore.Http.HttpContext httpContext) { throw null; } } } diff --git a/src/Middleware/Localization.Routing/src/RouteDataRequestCultureProvider.cs b/src/Middleware/Localization.Routing/src/RouteDataRequestCultureProvider.cs index c14db98721..415978d6fa 100644 --- a/src/Middleware/Localization.Routing/src/RouteDataRequestCultureProvider.cs +++ b/src/Middleware/Localization.Routing/src/RouteDataRequestCultureProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -59,8 +59,7 @@ namespace Microsoft.AspNetCore.Localization.Routing // Value for culture but not for UI culture so default to culture value for both uiCulture = culture; } - - if (culture == null && uiCulture != null) + else if (culture == null && uiCulture != null) { // Value for UI culture but not for culture so default to UI culture value for both culture = uiCulture; @@ -71,4 +70,4 @@ namespace Microsoft.AspNetCore.Localization.Routing return Task.FromResult(providerResultCulture); } } -} \ No newline at end of file +} diff --git a/src/Middleware/Localization/Localization.slnf b/src/Middleware/Localization/Localization.slnf new file mode 100644 index 0000000000..e4494b3619 --- /dev/null +++ b/src/Middleware/Localization/Localization.slnf @@ -0,0 +1,16 @@ +{ + "solution": { + "path": "..\\Middleware.sln", + "projects": [ + "Localization.Routing\\src\\Microsoft.AspNetCore.Localization.Routing.csproj", + "Localization.Routing\\test\\Microsoft.AspNetCore.Localization.Routing.Tests.csproj", + "Localization\\sample\\LocalizationSample.csproj", + "Localization\\src\\Microsoft.AspNetCore.Localization.csproj", + "Localization\\test\\FunctionalTests\\Microsoft.AspNetCore.Localization.FunctionalTests.csproj", + "Localization\\test\\UnitTests\\Microsoft.AspNetCore.Localization.Tests.csproj", + "Localization\\testassets\\LocalizationWebsite\\LocalizationWebsite.csproj", + "Localization\\testassets\\ResourcesClassLibraryNoAttribute\\ResourcesClassLibraryNoAttribute.csproj", + "Localization\\testassets\\ResourcesClassLibraryWithAttribute\\ResourcesClassLibraryWithAttribute.csproj" + ] + } +} \ No newline at end of file diff --git a/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp.cs b/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp.cs index 599db4aca6..c11d47ab7b 100644 --- a/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp.cs +++ b/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp.cs @@ -13,12 +13,13 @@ namespace Microsoft.AspNetCore.Builder public partial class RequestLocalizationOptions { public RequestLocalizationOptions() { } + public bool ApplyCurrentCultureToResponseHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Localization.RequestCulture DefaultRequestCulture { get { throw null; } set { } } - public bool FallBackToParentCultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool FallBackToParentUICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList RequestCultureProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList SupportedCultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList SupportedUICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool FallBackToParentCultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool FallBackToParentUICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList RequestCultureProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList SupportedCultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList SupportedUICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Builder.RequestLocalizationOptions AddSupportedCultures(params string[] cultures) { throw null; } public Microsoft.AspNetCore.Builder.RequestLocalizationOptions AddSupportedUICultures(params string[] uiCultures) { throw null; } public Microsoft.AspNetCore.Builder.RequestLocalizationOptions SetDefaultCulture(string defaultCulture) { throw null; } @@ -33,14 +34,14 @@ namespace Microsoft.AspNetCore.Localization public partial class AcceptLanguageHeaderRequestCultureProvider : Microsoft.AspNetCore.Localization.RequestCultureProvider { public AcceptLanguageHeaderRequestCultureProvider() { } - public int MaximumAcceptLanguageHeaderValuesToTry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int MaximumAcceptLanguageHeaderValuesToTry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task DetermineProviderCultureResult(Microsoft.AspNetCore.Http.HttpContext httpContext) { throw null; } } public partial class CookieRequestCultureProvider : Microsoft.AspNetCore.Localization.RequestCultureProvider { public static readonly string DefaultCookieName; public CookieRequestCultureProvider() { } - public string CookieName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string CookieName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task DetermineProviderCultureResult(Microsoft.AspNetCore.Http.HttpContext httpContext) { throw null; } public static string MakeCookieValue(Microsoft.AspNetCore.Localization.RequestCulture requestCulture) { throw null; } public static Microsoft.AspNetCore.Localization.ProviderCultureResult ParseCookieValue(string value) { throw null; } @@ -65,14 +66,14 @@ namespace Microsoft.AspNetCore.Localization public ProviderCultureResult(Microsoft.Extensions.Primitives.StringSegment culture, Microsoft.Extensions.Primitives.StringSegment uiCulture) { } public ProviderCultureResult(System.Collections.Generic.IList cultures) { } public ProviderCultureResult(System.Collections.Generic.IList cultures, System.Collections.Generic.IList uiCultures) { } - public System.Collections.Generic.IList Cultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList UICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Cultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList UICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class QueryStringRequestCultureProvider : Microsoft.AspNetCore.Localization.RequestCultureProvider { public QueryStringRequestCultureProvider() { } - public string QueryStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UIQueryStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string QueryStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UIQueryStringKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task DetermineProviderCultureResult(Microsoft.AspNetCore.Http.HttpContext httpContext) { throw null; } } public partial class RequestCulture @@ -81,20 +82,20 @@ namespace Microsoft.AspNetCore.Localization public RequestCulture(System.Globalization.CultureInfo culture, System.Globalization.CultureInfo uiCulture) { } public RequestCulture(string culture) { } public RequestCulture(string culture, string uiCulture) { } - public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Globalization.CultureInfo UICulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Globalization.CultureInfo UICulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class RequestCultureFeature : Microsoft.AspNetCore.Localization.IRequestCultureFeature { public RequestCultureFeature(Microsoft.AspNetCore.Localization.RequestCulture requestCulture, Microsoft.AspNetCore.Localization.IRequestCultureProvider provider) { } - public Microsoft.AspNetCore.Localization.IRequestCultureProvider Provider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Localization.RequestCulture RequestCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Localization.IRequestCultureProvider Provider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Localization.RequestCulture RequestCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class RequestCultureProvider : Microsoft.AspNetCore.Localization.IRequestCultureProvider { protected static readonly System.Threading.Tasks.Task NullProviderCultureResult; protected RequestCultureProvider() { } - public Microsoft.AspNetCore.Builder.RequestLocalizationOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Builder.RequestLocalizationOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.Threading.Tasks.Task DetermineProviderCultureResult(Microsoft.AspNetCore.Http.HttpContext httpContext); } public partial class RequestLocalizationMiddleware diff --git a/src/Middleware/Localization/src/CookieRequestCultureProvider.cs b/src/Middleware/Localization/src/CookieRequestCultureProvider.cs index 59a2891dbb..63b89fb611 100644 --- a/src/Middleware/Localization/src/CookieRequestCultureProvider.cs +++ b/src/Middleware/Localization/src/CookieRequestCultureProvider.cs @@ -109,8 +109,7 @@ namespace Microsoft.AspNetCore.Localization // Value for culture but not for UI culture so default to culture value for both uiCultureName = cultureName; } - - if (cultureName == null && uiCultureName != null) + else if (cultureName == null && uiCultureName != null) { // Value for UI culture but not for culture so default to UI culture value for both cultureName = uiCultureName; diff --git a/src/Middleware/Localization/src/QueryStringRequestCultureProvider.cs b/src/Middleware/Localization/src/QueryStringRequestCultureProvider.cs index 1f01c0d8c5..5cef93eb7c 100644 --- a/src/Middleware/Localization/src/QueryStringRequestCultureProvider.cs +++ b/src/Middleware/Localization/src/QueryStringRequestCultureProvider.cs @@ -64,8 +64,7 @@ namespace Microsoft.AspNetCore.Localization // Value for culture but not for UI culture so default to culture value for both queryUICulture = queryCulture; } - - if (queryCulture == null && queryUICulture != null) + else if (queryCulture == null && queryUICulture != null) { // Value for UI culture but not for culture so default to UI culture value for both queryCulture = queryUICulture; diff --git a/src/Middleware/Localization/src/RequestCulture.cs b/src/Middleware/Localization/src/RequestCulture.cs index 5aad1743ca..05dfe31a5e 100644 --- a/src/Middleware/Localization/src/RequestCulture.cs +++ b/src/Middleware/Localization/src/RequestCulture.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Localization public class RequestCulture { /// - /// Creates a new object has its and + /// Creates a new object with its and /// properties set to the same value. /// /// The for the request. @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Localization } /// - /// Creates a new object has its and + /// Creates a new object with its and /// properties set to the same value. /// /// The culture for the request. @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Localization } /// - /// Creates a new object has its and + /// Creates a new object with its and /// properties set to the respective values provided. /// /// The culture for the request to be used for formatting. @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Localization } /// - /// Creates a new object has its and + /// Creates a new object with its and /// properties set to the respective values provided. /// /// The for the request to be used for formatting. diff --git a/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs b/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs index c6ec3e1c06..fe56abcef4 100644 --- a/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs +++ b/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs @@ -1,5 +1,5 @@ -// 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. +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Localization { @@ -125,8 +126,7 @@ namespace Microsoft.AspNetCore.Localization { cultureInfo = _options.DefaultRequestCulture.Culture; } - - if (cultureInfo != null && uiCultureInfo == null) + else if (cultureInfo != null && uiCultureInfo == null) { uiCultureInfo = _options.DefaultRequestCulture.UICulture; } @@ -146,6 +146,11 @@ namespace Microsoft.AspNetCore.Localization SetCurrentThreadCulture(requestCulture); + if (_options.ApplyCurrentCultureToResponseHeaders) + { + context.Response.Headers.Add(HeaderNames.ContentLanguage, requestCulture.UICulture.Name); + } + await _next(context); } diff --git a/src/Middleware/Localization/src/RequestLocalizationOptions.cs b/src/Middleware/Localization/src/RequestLocalizationOptions.cs index 16776364f0..95ca74fe32 100644 --- a/src/Middleware/Localization/src/RequestLocalizationOptions.cs +++ b/src/Middleware/Localization/src/RequestLocalizationOptions.cs @@ -84,6 +84,11 @@ namespace Microsoft.AspNetCore.Builder /// public bool FallBackToParentUICultures { get; set; } = true; + /// + /// Gets or sets a value that determines if is applied to the response Content-Language header. + /// + public bool ApplyCurrentCultureToResponseHeaders { get; set; } + /// /// The cultures supported by the application. The will only set /// the current request culture to an entry in this list. diff --git a/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs b/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs index 5f09115be2..15b00dfacf 100644 --- a/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs +++ b/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs @@ -1,5 +1,5 @@ -// 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. +// 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.Net; @@ -14,6 +14,15 @@ namespace Microsoft.AspNetCore.Localization.FunctionalTests { public class LocalizationTest { + [Fact] + public Task Localization_ContentLanguageHeader() + { + return RunTest( + typeof(StartupContentLanguageHeader), + "ar-YE", + "True ar-YE"); + } + [Fact] public Task Localization_CustomCulture() { diff --git a/src/Middleware/Localization/testassets/LocalizationWebsite/StartupContentLanguageHeader.cs b/src/Middleware/Localization/testassets/LocalizationWebsite/StartupContentLanguageHeader.cs new file mode 100644 index 0000000000..849743184c --- /dev/null +++ b/src/Middleware/Localization/testassets/LocalizationWebsite/StartupContentLanguageHeader.cs @@ -0,0 +1,49 @@ +// 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.Collections.Generic; +using System.Globalization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Net.Http.Headers; + +namespace LocalizationWebsite +{ + public class StartupContentLanguageHeader + { + public void ConfigureServices(IServiceCollection services) + { + services.AddLocalization(); + } + + public void Configure( + IApplicationBuilder app) + { + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = new List() + { + new CultureInfo("ar-YE") + }, + SupportedUICultures = new List() + { + new CultureInfo("ar-YE") + }, + ApplyCurrentCultureToResponseHeaders = true + }); + + app.Run(async (context) => + { + var hasContentLanguageHeader = context.Response.Headers.ContainsKey(HeaderNames.ContentLanguage); + var contentLanguage = context.Response.Headers[HeaderNames.ContentLanguage].ToString(); + + await context.Response.WriteAsync(hasContentLanguageHeader.ToString()); + await context.Response.WriteAsync(" "); + await context.Response.WriteAsync(contentLanguage); + }); + } + } +} \ No newline at end of file diff --git a/src/Middleware/Localization/testassets/LocalizationWebsite/StartupResourcesInClassLibrary.cs b/src/Middleware/Localization/testassets/LocalizationWebsite/StartupResourcesInClassLibrary.cs index 092d09a37b..6cab0c27c6 100644 --- a/src/Middleware/Localization/testassets/LocalizationWebsite/StartupResourcesInClassLibrary.cs +++ b/src/Middleware/Localization/testassets/LocalizationWebsite/StartupResourcesInClassLibrary.cs @@ -39,7 +39,7 @@ namespace LocalizationWebsite }); var noAttributeStringLocalizer = stringLocalizerFactory.Create(typeof(ResourcesClassLibraryNoAttribute.Model)); - var withAttributeStringLocalizer = stringLocalizerFactory.Create(typeof(ResourcesClassLibraryWithAttribute.Model)); + var withAttributeStringLocalizer = stringLocalizerFactory.Create(typeof(Alternate.Namespace.Model)); var noAttributeAssembly = typeof(ResourcesClassLibraryNoAttribute.Model).GetTypeInfo().Assembly; var noAttributeName = new AssemblyName(noAttributeAssembly.FullName).Name; @@ -47,10 +47,10 @@ namespace LocalizationWebsite nameof(ResourcesClassLibraryNoAttribute.Model), noAttributeName); - var withAttributeAssembly = typeof(ResourcesClassLibraryWithAttribute.Model).GetTypeInfo().Assembly; + var withAttributeAssembly = typeof(Alternate.Namespace.Model).GetTypeInfo().Assembly; var withAttributeName = new AssemblyName(withAttributeAssembly.FullName).Name; var withAttributeNameStringLocalizer = stringLocalizerFactory.Create( - nameof(ResourcesClassLibraryWithAttribute.Model), + nameof(Alternate.Namespace.Model), withAttributeName); app.Run(async (context) => diff --git a/src/Middleware/Localization/testassets/ResourcesClassLibraryWithAttribute/Model.cs b/src/Middleware/Localization/testassets/ResourcesClassLibraryWithAttribute/Model.cs index c6ca99afa8..b1ff90f523 100644 --- a/src/Middleware/Localization/testassets/ResourcesClassLibraryWithAttribute/Model.cs +++ b/src/Middleware/Localization/testassets/ResourcesClassLibraryWithAttribute/Model.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace ResourcesClassLibraryWithAttribute +namespace Alternate.Namespace { public class Model { diff --git a/src/Middleware/Middleware.sln b/src/Middleware/Middleware.sln index e09bbfb88c..b0f2023e7b 100644 --- a/src/Middleware/Middleware.sln +++ b/src/Middleware/Middleware.sln @@ -293,6 +293,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices.Extensions.Tests", "SpaServices.Extensions\test\Microsoft.AspNetCore.SpaServices.Extensions.Tests.csproj", "{D0CB733B-4CE8-4F6C-BBB9-548EA1A96966}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets.Microbenchmarks", "perf\Microbenchmarks\Microsoft.AspNetCore.WebSockets.Microbenchmarks.csproj", "{C4D624B3-749E-41D8-A43B-B304BC3885EA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Perf", "Perf", "{4623F52E-2070-4631-8DEE-7D2F48733FFD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1599,6 +1603,18 @@ Global {D0CB733B-4CE8-4F6C-BBB9-548EA1A96966}.Release|x64.Build.0 = Release|Any CPU {D0CB733B-4CE8-4F6C-BBB9-548EA1A96966}.Release|x86.ActiveCfg = Release|Any CPU {D0CB733B-4CE8-4F6C-BBB9-548EA1A96966}.Release|x86.Build.0 = Release|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Debug|x64.ActiveCfg = Debug|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Debug|x64.Build.0 = Debug|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Debug|x86.ActiveCfg = Debug|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Debug|x86.Build.0 = Debug|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Release|Any CPU.Build.0 = Release|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Release|x64.ActiveCfg = Release|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Release|x64.Build.0 = Release|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Release|x86.ActiveCfg = Release|Any CPU + {C4D624B3-749E-41D8-A43B-B304BC3885EA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1725,6 +1741,7 @@ Global {46B4FE62-06A1-4D54-B3E8-D8B4B3560075} = {ACA6DDB9-7592-47CE-A740-D15BF307E9E0} {92E11EBB-759E-4DA8-AB61-A9977D9F97D0} = {ACA6DDB9-7592-47CE-A740-D15BF307E9E0} {D0CB733B-4CE8-4F6C-BBB9-548EA1A96966} = {D6FA4ABE-E685-4EDD-8B06-D8777E76B472} + {C4D624B3-749E-41D8-A43B-B304BC3885EA} = {4623F52E-2070-4631-8DEE-7D2F48733FFD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {83786312-A93B-4BB4-AB06-7C6913A59AFA} diff --git a/src/Middleware/NodeServices/ref/Microsoft.AspNetCore.NodeServices.netcoreapp.cs b/src/Middleware/NodeServices/ref/Microsoft.AspNetCore.NodeServices.netcoreapp.cs index c57f1991df..99474350fe 100644 --- a/src/Middleware/NodeServices/ref/Microsoft.AspNetCore.NodeServices.netcoreapp.cs +++ b/src/Middleware/NodeServices/ref/Microsoft.AspNetCore.NodeServices.netcoreapp.cs @@ -27,21 +27,21 @@ namespace Microsoft.AspNetCore.NodeServices public partial class NodeServicesOptions { public NodeServicesOptions(System.IServiceProvider serviceProvider) { } - public System.Threading.CancellationToken ApplicationStoppingToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int DebuggingPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary EnvironmentVariables { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int InvocationTimeoutMilliseconds { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool LaunchWithDebugging { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func NodeInstanceFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Extensions.Logging.ILogger NodeInstanceOutputLogger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProjectPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] WatchFileExtensions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Threading.CancellationToken ApplicationStoppingToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int DebuggingPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary EnvironmentVariables { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int InvocationTimeoutMilliseconds { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool LaunchWithDebugging { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func NodeInstanceFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Extensions.Logging.ILogger NodeInstanceOutputLogger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProjectPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] WatchFileExtensions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.ObsoleteAttribute("Use Microsoft.AspNetCore.SpaServices.Extensions")] public sealed partial class StringAsTempFile : System.IDisposable { public StringAsTempFile(string content, System.Threading.CancellationToken applicationStoppingToken) { } - public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Dispose() { } ~StringAsTempFile() { } } @@ -58,16 +58,16 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels { public NodeInvocationException(string message, string details) { } public NodeInvocationException(string message, string details, bool nodeInstanceUnavailable, bool allowConnectionDraining) { } - public bool AllowConnectionDraining { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool NodeInstanceUnavailable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AllowConnectionDraining { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool NodeInstanceUnavailable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.ObsoleteAttribute("Use Microsoft.AspNetCore.SpaServices.Extensions")] public partial class NodeInvocationInfo { public NodeInvocationInfo() { } - public object[] Args { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ExportedFunctionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ModuleName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object[] Args { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ExportedFunctionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ModuleName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.ObsoleteAttribute("Use Microsoft.AspNetCore.SpaServices.Extensions")] public static partial class NodeServicesOptionsExtensions diff --git a/src/Middleware/ResponseCaching/ref/Microsoft.AspNetCore.ResponseCaching.netcoreapp.cs b/src/Middleware/ResponseCaching/ref/Microsoft.AspNetCore.ResponseCaching.netcoreapp.cs index 1cb8861848..4824ecefd5 100644 --- a/src/Middleware/ResponseCaching/ref/Microsoft.AspNetCore.ResponseCaching.netcoreapp.cs +++ b/src/Middleware/ResponseCaching/ref/Microsoft.AspNetCore.ResponseCaching.netcoreapp.cs @@ -24,9 +24,9 @@ namespace Microsoft.AspNetCore.ResponseCaching public partial class ResponseCachingOptions { public ResponseCachingOptions() { } - public long MaximumBodySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long SizeLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool UseCaseSensitivePaths { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public long MaximumBodySize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long SizeLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool UseCaseSensitivePaths { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Middleware/ResponseCaching/src/Interfaces/IResponseCache.cs b/src/Middleware/ResponseCaching/src/Interfaces/IResponseCache.cs index 4ca2c6e8d1..6b6f95fab3 100644 --- a/src/Middleware/ResponseCaching/src/Interfaces/IResponseCache.cs +++ b/src/Middleware/ResponseCaching/src/Interfaces/IResponseCache.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -16,14 +16,6 @@ namespace Microsoft.AspNetCore.ResponseCaching /// The response cache entry if it exists; otherwise null. IResponseCacheEntry Get(string key); - /// - /// Gets the cached response for the given key, if it exists. - /// If no cached response exists for the given key, null is returned. - /// - /// The cache key to look up. - /// The response cache entry if it exists; otherwise null. - Task GetAsync(string key); - /// /// Stores the given response in the response cache. /// @@ -31,14 +23,5 @@ namespace Microsoft.AspNetCore.ResponseCaching /// The response cache entry to store. /// The amount of time the entry will be kept in the cache before expiring, relative to now. void Set(string key, IResponseCacheEntry entry, TimeSpan validFor); - - /// - /// Stores the given response in the response cache. - /// - /// The cache key to store the response under. - /// The response cache entry to store. - /// The amount of time the entry will be kept in the cache before expiring, relative to now. - /// No result is returned. - Task SetAsync(string key, IResponseCacheEntry entry, TimeSpan validFor); } } diff --git a/src/Middleware/ResponseCaching/src/MemoryResponseCache.cs b/src/Middleware/ResponseCaching/src/MemoryResponseCache.cs index 554ab361d8..b3fee366f7 100644 --- a/src/Middleware/ResponseCaching/src/MemoryResponseCache.cs +++ b/src/Middleware/ResponseCaching/src/MemoryResponseCache.cs @@ -36,11 +36,6 @@ namespace Microsoft.AspNetCore.ResponseCaching } } - public Task GetAsync(string key) - { - return Task.FromResult(Get(key)); - } - public void Set(string key, IResponseCacheEntry entry, TimeSpan validFor) { if (entry is CachedResponse cachedResponse) @@ -76,11 +71,5 @@ namespace Microsoft.AspNetCore.ResponseCaching }); } } - - public Task SetAsync(string key, IResponseCacheEntry entry, TimeSpan validFor) - { - Set(key, entry, validFor); - return Task.CompletedTask; - } } } diff --git a/src/Middleware/ResponseCaching/src/ResponseCachingMiddleware.cs b/src/Middleware/ResponseCaching/src/ResponseCachingMiddleware.cs index d679559da7..758bcb1d85 100644 --- a/src/Middleware/ResponseCaching/src/ResponseCachingMiddleware.cs +++ b/src/Middleware/ResponseCaching/src/ResponseCachingMiddleware.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.ObjectPool; @@ -113,10 +112,10 @@ namespace Microsoft.AspNetCore.ResponseCaching await _next(httpContext); // If there was no response body, check the response headers now. We can cache things like redirects. - await StartResponseAsync(context); + StartResponse(context); // Finalize the cache entry - await FinalizeCacheBodyAsync(context); + FinalizeCacheBody(context); } finally { @@ -211,7 +210,7 @@ namespace Microsoft.AspNetCore.ResponseCaching internal async Task TryServeFromCacheAsync(ResponseCachingContext context) { context.BaseKey = _keyProvider.CreateBaseKey(context); - var cacheEntry = await _cache.GetAsync(context.BaseKey); + var cacheEntry = _cache.Get(context.BaseKey); if (cacheEntry is CachedVaryByRules cachedVaryByRules) { @@ -220,7 +219,7 @@ namespace Microsoft.AspNetCore.ResponseCaching foreach (var varyKey in _keyProvider.CreateLookupVaryByKeys(context)) { - if (await TryServeCachedResponseAsync(context, await _cache.GetAsync(varyKey))) + if (await TryServeCachedResponseAsync(context, _cache.Get(varyKey))) { return true; } @@ -339,22 +338,15 @@ namespace Microsoft.AspNetCore.ResponseCaching } } - internal Task FinalizeCacheHeadersAsync(ResponseCachingContext context) - { - if (OnFinalizeCacheHeaders(context)) - { - return _cache.SetAsync(context.BaseKey, context.CachedVaryByRules, context.CachedResponseValidFor); - } - return Task.CompletedTask; - } - - internal async Task FinalizeCacheBodyAsync(ResponseCachingContext context) + internal void FinalizeCacheBody(ResponseCachingContext context) { if (context.ShouldCacheResponse && context.ResponseCachingStream.BufferingEnabled) { var contentLength = context.HttpContext.Response.ContentLength; var bufferStream = context.ResponseCachingStream.GetBufferStream(); - if (!contentLength.HasValue || contentLength == bufferStream.Length) + if (!contentLength.HasValue || contentLength == bufferStream.Length + || (bufferStream.Length == 0 + && HttpMethods.IsHead(context.HttpContext.Request.Method))) { var response = context.HttpContext.Response; // Add a content-length if required @@ -365,7 +357,7 @@ namespace Microsoft.AspNetCore.ResponseCaching context.CachedResponse.Body = bufferStream; _logger.ResponseCached(); - await _cache.SetAsync(context.StorageVaryKey ?? context.BaseKey, context.CachedResponse, context.CachedResponseValidFor); + _cache.Set(context.StorageVaryKey ?? context.BaseKey, context.CachedResponse, context.CachedResponseValidFor); } else { @@ -403,15 +395,6 @@ namespace Microsoft.AspNetCore.ResponseCaching } } - internal Task StartResponseAsync(ResponseCachingContext context) - { - if (OnStartResponse(context)) - { - return FinalizeCacheHeadersAsync(context); - } - return Task.CompletedTask; - } - internal static void AddResponseCachingFeature(HttpContext context) { if (context.Features.Get() != null) @@ -429,8 +412,7 @@ namespace Microsoft.AspNetCore.ResponseCaching context.OriginalResponseStream, _options.MaximumBodySize, StreamUtilities.BodySegmentSize, - () => StartResponse(context), - () => StartResponseAsync(context)); + () => StartResponse(context)); context.HttpContext.Response.Body = context.ResponseCachingStream; // Add IResponseCachingFeature diff --git a/src/Middleware/ResponseCaching/src/Streams/ResponseCachingStream.cs b/src/Middleware/ResponseCaching/src/Streams/ResponseCachingStream.cs index a788778e94..f6d705e1f1 100644 --- a/src/Middleware/ResponseCaching/src/Streams/ResponseCachingStream.cs +++ b/src/Middleware/ResponseCaching/src/Streams/ResponseCachingStream.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -15,15 +15,13 @@ namespace Microsoft.AspNetCore.ResponseCaching private readonly int _segmentSize; private readonly SegmentWriteStream _segmentWriteStream; private readonly Action _startResponseCallback; - private readonly Func _startResponseCallbackAsync; - internal ResponseCachingStream(Stream innerStream, long maxBufferSize, int segmentSize, Action startResponseCallback, Func startResponseCallbackAsync) + internal ResponseCachingStream(Stream innerStream, long maxBufferSize, int segmentSize, Action startResponseCallback) { _innerStream = innerStream; _maxBufferSize = maxBufferSize; _segmentSize = segmentSize; _startResponseCallback = startResponseCallback; - _startResponseCallbackAsync = startResponseCallbackAsync; _segmentWriteStream = new SegmentWriteStream(_segmentSize); } @@ -92,7 +90,7 @@ namespace Microsoft.AspNetCore.ResponseCaching { try { - await _startResponseCallbackAsync(); + _startResponseCallback(); await _innerStream.FlushAsync(); } catch @@ -136,7 +134,7 @@ namespace Microsoft.AspNetCore.ResponseCaching { try { - await _startResponseCallbackAsync(); + _startResponseCallback(); await _innerStream.WriteAsync(buffer, offset, count, cancellationToken); } catch diff --git a/src/Middleware/ResponseCaching/test/ResponseCachingMiddlewareTests.cs b/src/Middleware/ResponseCaching/test/ResponseCachingMiddlewareTests.cs index 43970711ea..68adab8c09 100644 --- a/src/Middleware/ResponseCaching/test/ResponseCachingMiddlewareTests.cs +++ b/src/Middleware/ResponseCaching/test/ResponseCachingMiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache, keyProvider: new TestResponseCachingKeyProvider("BaseKey")); var context = TestUtils.CreateTestContext(); - await cache.SetAsync( + cache.Set( "BaseKey", new CachedResponse() { @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var context = TestUtils.CreateTestContext(); context.HttpContext.Response.Headers["MyHeader"] = "OldValue"; - await cache.SetAsync( + cache.Set( "BaseKey", new CachedResponse() { @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache, keyProvider: new TestResponseCachingKeyProvider("BaseKey", "VaryKey")); var context = TestUtils.CreateTestContext(); - await cache.SetAsync( + cache.Set( "BaseKey", new CachedVaryByRules(), TimeSpan.Zero); @@ -131,11 +131,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache, keyProvider: new TestResponseCachingKeyProvider("BaseKey", new[] { "VaryKey", "VaryKey2" })); var context = TestUtils.CreateTestContext(); - await cache.SetAsync( + cache.Set( "BaseKey", new CachedVaryByRules(), TimeSpan.Zero); - await cache.SetAsync( + cache.Set( "BaseKeyVaryKey2", new CachedResponse() { @@ -160,7 +160,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var context = TestUtils.CreateTestContext(); context.HttpContext.Request.Headers[HeaderNames.IfNoneMatch] = "*"; - await cache.SetAsync( + cache.Set( "BaseKey", new CachedResponse() { @@ -358,7 +358,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests } [Fact] - public async Task StartResponsegAsync_IfAllowResponseCaptureIsTrue_SetsResponseTime() + public void StartResponsegAsync_IfAllowResponseCaptureIsTrue_SetsResponseTime() { var clock = new TestClock { @@ -371,13 +371,13 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var context = TestUtils.CreateTestContext(); context.ResponseTime = null; - await middleware.StartResponseAsync(context); + middleware.StartResponse(context); Assert.Equal(clock.UtcNow, context.ResponseTime); } [Fact] - public async Task StartResponseAsync_IfAllowResponseCaptureIsTrue_SetsResponseTimeOnlyOnce() + public void StartResponseAsync_IfAllowResponseCaptureIsTrue_SetsResponseTimeOnlyOnce() { var clock = new TestClock { @@ -391,18 +391,18 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests var initialTime = clock.UtcNow; context.ResponseTime = null; - await middleware.StartResponseAsync(context); + middleware.StartResponse(context); Assert.Equal(initialTime, context.ResponseTime); clock.UtcNow += TimeSpan.FromSeconds(10); - await middleware.StartResponseAsync(context); + middleware.StartResponse(context); Assert.NotEqual(clock.UtcNow, context.ResponseTime); Assert.Equal(initialTime, context.ResponseTime); } [Fact] - public async Task FinalizeCacheHeadersAsync_UpdateShouldCacheResponse_IfResponseCacheable() + public void FinalizeCacheHeadersAsync_UpdateShouldCacheResponse_IfResponseCacheable() { var sink = new TestSink(); var middleware = TestUtils.CreateTestMiddleware(testSink: sink, policyProvider: new ResponseCachingPolicyProvider()); @@ -415,14 +415,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests Assert.False(context.ShouldCacheResponse); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.True(context.ShouldCacheResponse); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_DoNotUpdateShouldCacheResponse_IfResponseIsNotCacheable() + public void FinalizeCacheHeadersAsync_DoNotUpdateShouldCacheResponse_IfResponseIsNotCacheable() { var sink = new TestSink(); var middleware = TestUtils.CreateTestMiddleware(testSink: sink, policyProvider: new ResponseCachingPolicyProvider()); @@ -430,27 +430,27 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests middleware.ShimResponseStream(context); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.False(context.ShouldCacheResponse); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_DefaultResponseValidity_Is10Seconds() + public void FinalizeCacheHeadersAsync_DefaultResponseValidity_Is10Seconds() { var sink = new TestSink(); var middleware = TestUtils.CreateTestMiddleware(testSink: sink); var context = TestUtils.CreateTestContext(); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(TimeSpan.FromSeconds(10), context.CachedResponseValidFor); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_ResponseValidity_UseExpiryIfAvailable() + public void FinalizeCacheHeadersAsync_ResponseValidity_UseExpiryIfAvailable() { var clock = new TestClock { @@ -466,14 +466,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.ResponseTime = clock.UtcNow; context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(clock.UtcNow + TimeSpan.FromSeconds(11)); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(TimeSpan.FromSeconds(11), context.CachedResponseValidFor); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_ResponseValidity_UseMaxAgeIfAvailable() + public void FinalizeCacheHeadersAsync_ResponseValidity_UseMaxAgeIfAvailable() { var clock = new TestClock { @@ -494,14 +494,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(clock.UtcNow + TimeSpan.FromSeconds(11)); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(TimeSpan.FromSeconds(12), context.CachedResponseValidFor); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_ResponseValidity_UseSharedMaxAgeIfAvailable() + public void FinalizeCacheHeadersAsync_ResponseValidity_UseSharedMaxAgeIfAvailable() { var clock = new TestClock { @@ -522,14 +522,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests }.ToString(); context.HttpContext.Response.Headers[HeaderNames.Expires] = HeaderUtilities.FormatDate(clock.UtcNow + TimeSpan.FromSeconds(11)); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(TimeSpan.FromSeconds(13), context.CachedResponseValidFor); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_UpdateCachedVaryByRules_IfNotEquivalentToPrevious() + public void FinalizeCacheHeadersAsync_UpdateCachedVaryByRules_IfNotEquivalentToPrevious() { var cache = new TestResponseCache(); var sink = new TestSink(); @@ -548,7 +548,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests }; context.CachedVaryByRules = cachedVaryByRules; - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(1, cache.SetCount); Assert.NotSame(cachedVaryByRules, context.CachedVaryByRules); @@ -558,7 +558,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests } [Fact] - public async Task FinalizeCacheHeadersAsync_UpdateCachedVaryByRules_IfEquivalentToPrevious() + public void FinalizeCacheHeadersAsync_UpdateCachedVaryByRules_IfEquivalentToPrevious() { var cache = new TestResponseCache(); var sink = new TestSink(); @@ -578,7 +578,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests }; context.CachedVaryByRules = cachedVaryByRules; - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); // An update to the cache is always made but the entry should be the same Assert.Equal(1, cache.SetCount); @@ -608,7 +608,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests [Theory] [MemberData(nameof(NullOrEmptyVaryRules))] - public async Task FinalizeCacheHeadersAsync_UpdateCachedVaryByRules_NullOrEmptyRules(StringValues vary) + public void FinalizeCacheHeadersAsync_UpdateCachedVaryByRules_NullOrEmptyRules(StringValues vary) { var cache = new TestResponseCache(); var sink = new TestSink(); @@ -621,7 +621,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests VaryByQueryKeys = vary }); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); // Vary rules should not be updated Assert.Equal(0, cache.SetCount); @@ -629,7 +629,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests } [Fact] - public async Task FinalizeCacheHeadersAsync_AddsDate_IfNoneSpecified() + public void FinalizeCacheHeadersAsync_AddsDate_IfNoneSpecified() { var utcNow = DateTimeOffset.UtcNow; var sink = new TestSink(); @@ -640,14 +640,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests Assert.True(StringValues.IsNullOrEmpty(context.HttpContext.Response.Headers[HeaderNames.Date])); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_DoNotAddDate_IfSpecified() + public void FinalizeCacheHeadersAsync_DoNotAddDate_IfSpecified() { var utcNow = DateTimeOffset.MinValue; var sink = new TestSink(); @@ -659,14 +659,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(HeaderUtilities.FormatDate(utcNow), context.HttpContext.Response.Headers[HeaderNames.Date]); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_StoresCachedResponse_InState() + public void FinalizeCacheHeadersAsync_StoresCachedResponse_InState() { var sink = new TestSink(); var middleware = TestUtils.CreateTestMiddleware(testSink: sink); @@ -674,14 +674,14 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests Assert.Null(context.CachedResponse); - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.NotNull(context.CachedResponse); Assert.Empty(sink.Writes); } [Fact] - public async Task FinalizeCacheHeadersAsync_SplitsVaryHeaderByCommas() + public void FinalizeCacheHeadersAsync_SplitsVaryHeaderByCommas() { var sink = new TestSink(); var middleware = TestUtils.CreateTestMiddleware(testSink: sink); @@ -689,7 +689,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.HttpContext.Response.Headers[HeaderNames.Vary] = "HeaderB, heaDera"; - await middleware.FinalizeCacheHeadersAsync(context); + middleware.FinalizeCacheHeaders(context); Assert.Equal(new StringValues(new[] { "HEADERA", "HEADERB" }), context.CachedVaryByRules.Headers); TestUtils.AssertLoggedMessages( @@ -715,7 +715,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.BaseKey = "BaseKey"; context.CachedResponseValidFor = TimeSpan.FromSeconds(10); - await middleware.FinalizeCacheBodyAsync(context); + middleware.FinalizeCacheBody(context); Assert.Equal(1, cache.SetCount); TestUtils.AssertLoggedMessages( @@ -723,8 +723,10 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests LoggedMessage.ResponseCached); } - [Fact] - public async Task FinalizeCacheBody_DoNotCache_IfContentLengthMismatches() + [Theory] + [InlineData("GET")] + [InlineData("HEAD")] + public async Task FinalizeCacheBody_DoNotCache_IfContentLengthMismatches(string method) { var cache = new TestResponseCache(); var sink = new TestSink(); @@ -734,6 +736,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.ShouldCacheResponse = true; middleware.ShimResponseStream(context); context.HttpContext.Response.ContentLength = 9; + context.HttpContext.Request.Method = method; await context.HttpContext.Response.WriteAsync(new string('0', 10)); @@ -741,7 +744,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.BaseKey = "BaseKey"; context.CachedResponseValidFor = TimeSpan.FromSeconds(10); - await middleware.FinalizeCacheBodyAsync(context); + middleware.FinalizeCacheBody(context); Assert.Equal(0, cache.SetCount); TestUtils.AssertLoggedMessages( @@ -749,6 +752,39 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests LoggedMessage.ResponseContentLengthMismatchNotCached); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task FinalizeCacheBody_RequestHead_Cache_IfContentLengthPresent_AndBodyAbsentOrOfSameLength(bool includeBody) + { + var cache = new TestResponseCache(); + var sink = new TestSink(); + var middleware = TestUtils.CreateTestMiddleware(testSink: sink, cache: cache); + var context = TestUtils.CreateTestContext(); + + context.ShouldCacheResponse = true; + middleware.ShimResponseStream(context); + context.HttpContext.Response.ContentLength = 10; + context.HttpContext.Request.Method = "HEAD"; + + if (includeBody) + { + // A response to HEAD should not include a body, but it may be present + await context.HttpContext.Response.WriteAsync(new string('0', 10)); + } + + context.CachedResponse = new CachedResponse(); + context.BaseKey = "BaseKey"; + context.CachedResponseValidFor = TimeSpan.FromSeconds(10); + + middleware.FinalizeCacheBody(context); + + Assert.Equal(1, cache.SetCount); + TestUtils.AssertLoggedMessages( + sink.Writes, + LoggedMessage.ResponseCached); + } + [Fact] public async Task FinalizeCacheBody_Cache_IfContentLengthAbsent() { @@ -769,7 +805,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.BaseKey = "BaseKey"; context.CachedResponseValidFor = TimeSpan.FromSeconds(10); - await middleware.FinalizeCacheBodyAsync(context); + middleware.FinalizeCacheBody(context); Assert.Equal(1, cache.SetCount); TestUtils.AssertLoggedMessages( @@ -789,7 +825,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests await context.HttpContext.Response.WriteAsync(new string('0', 10)); context.ShouldCacheResponse = false; - await middleware.FinalizeCacheBodyAsync(context); + middleware.FinalizeCacheBody(context); Assert.Equal(0, cache.SetCount); TestUtils.AssertLoggedMessages( @@ -811,7 +847,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.ResponseCachingStream.DisableBuffering(); - await middleware.FinalizeCacheBodyAsync(context); + middleware.FinalizeCacheBody(context); Assert.Equal(0, cache.SetCount); TestUtils.AssertLoggedMessages( @@ -840,7 +876,7 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests context.CachedResponse = new CachedResponse() { Headers = new HeaderDictionary() }; context.CachedResponseValidFor = TimeSpan.FromSeconds(10); - await middleware.FinalizeCacheBodyAsync(context); + middleware.FinalizeCacheBody(context); // The response cached message will be logged but the adding of the entry will no-op TestUtils.AssertLoggedMessages( diff --git a/src/Middleware/ResponseCaching/test/ResponseCachingTests.cs b/src/Middleware/ResponseCaching/test/ResponseCachingTests.cs index 2a3bb3fde4..522b6952c2 100644 --- a/src/Middleware/ResponseCaching/test/ResponseCachingTests.cs +++ b/src/Middleware/ResponseCaching/test/ResponseCachingTests.cs @@ -2,13 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.IO; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.TestHost; using Microsoft.Net.Http.Headers; using Xunit; @@ -775,6 +771,24 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests } } + [Fact] + public async Task ServesCachedContent_IfAvailable_UsingHead_WithContentLength() + { + var builders = TestUtils.CreateBuildersWithResponseCaching(); + + foreach (var builder in builders) + { + using (var server = new TestServer(builder)) + { + var client = server.CreateClient(); + var initialResponse = await client.SendAsync(TestUtils.CreateRequest("HEAD", "?contentLength=10")); + var subsequentResponse = await client.SendAsync(TestUtils.CreateRequest("HEAD", "?contentLength=10")); + + await AssertCachedResponseAsync(initialResponse, subsequentResponse); + } + } + } + private static void Assert304Headers(HttpResponseMessage initialResponse, HttpResponseMessage subsequentResponse) { // https://tools.ietf.org/html/rfc7232#section-4.1 diff --git a/src/Middleware/ResponseCaching/test/TestUtils.cs b/src/Middleware/ResponseCaching/test/TestUtils.cs index 00e2308b05..270778f996 100644 --- a/src/Middleware/ResponseCaching/test/TestUtils.cs +++ b/src/Middleware/ResponseCaching/test/TestUtils.cs @@ -4,11 +4,9 @@ using System; using System.Collections.Generic; using System.IO; -using System.IO.Pipelines; using System.Linq; using System.Net.Http; using System.Text; -using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -23,7 +21,6 @@ using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; using Xunit; -using ISystemClock = Microsoft.AspNetCore.ResponseCaching.ISystemClock; namespace Microsoft.AspNetCore.ResponseCaching.Tests { @@ -61,6 +58,12 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests headers.Date = DateTimeOffset.UtcNow; headers.Headers["X-Value"] = guid; + var contentLength = context.Request.Query["ContentLength"]; + if (!string.IsNullOrEmpty(contentLength)) + { + headers.ContentLength = long.Parse(contentLength); + } + if (context.Request.Method != "HEAD") { return true; @@ -385,22 +388,11 @@ namespace Microsoft.AspNetCore.ResponseCaching.Tests } } - public Task GetAsync(string key) - { - return Task.FromResult(Get(key)); - } - public void Set(string key, IResponseCacheEntry entry, TimeSpan validFor) { SetCount++; _storage[key] = entry; } - - public Task SetAsync(string key, IResponseCacheEntry entry, TimeSpan validFor) - { - Set(key, entry, validFor); - return Task.CompletedTask; - } } internal class TestClock : ISystemClock diff --git a/src/Middleware/ResponseCompression/ref/Microsoft.AspNetCore.ResponseCompression.netcoreapp.cs b/src/Middleware/ResponseCompression/ref/Microsoft.AspNetCore.ResponseCompression.netcoreapp.cs index 471bd3a742..3d2ee597b2 100644 --- a/src/Middleware/ResponseCompression/ref/Microsoft.AspNetCore.ResponseCompression.netcoreapp.cs +++ b/src/Middleware/ResponseCompression/ref/Microsoft.AspNetCore.ResponseCompression.netcoreapp.cs @@ -18,14 +18,14 @@ namespace Microsoft.AspNetCore.ResponseCompression public partial class BrotliCompressionProvider : Microsoft.AspNetCore.ResponseCompression.ICompressionProvider { public BrotliCompressionProvider(Microsoft.Extensions.Options.IOptions options) { } - public string EncodingName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool SupportsFlush { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string EncodingName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool SupportsFlush { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.IO.Stream CreateStream(System.IO.Stream outputStream) { throw null; } } public partial class BrotliCompressionProviderOptions : Microsoft.Extensions.Options.IOptions { public BrotliCompressionProviderOptions() { } - public System.IO.Compression.CompressionLevel Level { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Compression.CompressionLevel Level { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } Microsoft.AspNetCore.ResponseCompression.BrotliCompressionProviderOptions Microsoft.Extensions.Options.IOptions.Value { get { throw null; } } } public partial class CompressionProviderCollection : System.Collections.ObjectModel.Collection @@ -37,14 +37,14 @@ namespace Microsoft.AspNetCore.ResponseCompression public partial class GzipCompressionProvider : Microsoft.AspNetCore.ResponseCompression.ICompressionProvider { public GzipCompressionProvider(Microsoft.Extensions.Options.IOptions options) { } - public string EncodingName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string EncodingName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool SupportsFlush { get { throw null; } } public System.IO.Stream CreateStream(System.IO.Stream outputStream) { throw null; } } public partial class GzipCompressionProviderOptions : Microsoft.Extensions.Options.IOptions { public GzipCompressionProviderOptions() { } - public System.IO.Compression.CompressionLevel Level { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Compression.CompressionLevel Level { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } Microsoft.AspNetCore.ResponseCompression.GzipCompressionProviderOptions Microsoft.Extensions.Options.IOptions.Value { get { throw null; } } } public partial interface ICompressionProvider @@ -73,10 +73,10 @@ namespace Microsoft.AspNetCore.ResponseCompression public partial class ResponseCompressionOptions { public ResponseCompressionOptions() { } - public bool EnableForHttps { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IEnumerable ExcludedMimeTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IEnumerable MimeTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.ResponseCompression.CompressionProviderCollection Providers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool EnableForHttps { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IEnumerable ExcludedMimeTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IEnumerable MimeTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.ResponseCompression.CompressionProviderCollection Providers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ResponseCompressionProvider : Microsoft.AspNetCore.ResponseCompression.IResponseCompressionProvider { diff --git a/src/Middleware/ResponseCompression/src/ResponseCompressionProvider.cs b/src/Middleware/ResponseCompression/src/ResponseCompressionProvider.cs index ad29ab7b2c..8592f25260 100644 --- a/src/Middleware/ResponseCompression/src/ResponseCompressionProvider.cs +++ b/src/Middleware/ResponseCompression/src/ResponseCompressionProvider.cs @@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.ResponseCompression return null; } - if (!StringWithQualityHeaderValue.TryParseList(accept, out var encodings) || !encodings.Any()) + if (!StringWithQualityHeaderValue.TryParseList(accept, out var encodings) || encodings.Count == 0) { _logger.NoAcceptEncoding(); return null; diff --git a/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.netcoreapp.cs b/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.netcoreapp.cs index 4a2f965186..77c01f304a 100644 --- a/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.netcoreapp.cs +++ b/src/Middleware/Rewrite/ref/Microsoft.AspNetCore.Rewrite.netcoreapp.cs @@ -28,10 +28,10 @@ namespace Microsoft.AspNetCore.Rewrite public partial class RewriteContext { public RewriteContext() { } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Rewrite.RuleResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Extensions.FileProviders.IFileProvider StaticFileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Rewrite.RuleResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Extensions.FileProviders.IFileProvider StaticFileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RewriteMiddleware { @@ -41,8 +41,8 @@ namespace Microsoft.AspNetCore.Rewrite public partial class RewriteOptions { public RewriteOptions() { } - public System.Collections.Generic.IList Rules { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.FileProviders.IFileProvider StaticFileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList Rules { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.FileProviders.IFileProvider StaticFileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class RewriteOptionsExtensions { @@ -54,6 +54,12 @@ namespace Microsoft.AspNetCore.Rewrite public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttps(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; } public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttps(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, int? sslPort) { throw null; } public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToHttpsPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; } + public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; } + public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; } + public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, params string[] domains) { throw null; } + public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, params string[] domains) { throw null; } + public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWwwPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; } + public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToNonWwwPermanent(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, params string[] domains) { throw null; } public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options) { throw null; } public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode) { throw null; } public static Microsoft.AspNetCore.Rewrite.RewriteOptions AddRedirectToWww(this Microsoft.AspNetCore.Rewrite.RewriteOptions options, int statusCode, params string[] domains) { throw null; } diff --git a/src/Middleware/Rewrite/src/Extensions/RewriteMiddlewareLoggingExtensions.cs b/src/Middleware/Rewrite/src/Extensions/RewriteMiddlewareLoggingExtensions.cs index 4e35fc478c..177469464f 100644 --- a/src/Middleware/Rewrite/src/Extensions/RewriteMiddlewareLoggingExtensions.cs +++ b/src/Middleware/Rewrite/src/Extensions/RewriteMiddlewareLoggingExtensions.cs @@ -17,6 +17,7 @@ namespace Microsoft.AspNetCore.Rewrite.Logging private static readonly Action _modRewriteMatchedRule; private static readonly Action _redirectedToHttps; private static readonly Action _redirectedToWww; + private static readonly Action _redirectedToNonWww; private static readonly Action _redirectedRequest; private static readonly Action _rewrittenRequest; private static readonly Action _abortedRequest; @@ -88,6 +89,11 @@ namespace Microsoft.AspNetCore.Rewrite.Logging LogLevel.Information, new EventId(13, "RedirectedToWww"), "Request redirected to www"); + + _redirectedToNonWww = LoggerMessage.Define( + LogLevel.Information, + new EventId(14, "RedirectedToNonWww"), + "Request redirected to root domain from www subdomain"); } public static void RewriteMiddlewareRequestContinueResults(this ILogger logger, string currentUrl) @@ -135,6 +141,11 @@ namespace Microsoft.AspNetCore.Rewrite.Logging _redirectedToWww(logger, null); } + public static void RedirectedToNonWww(this ILogger logger) + { + _redirectedToNonWww(logger, null); + } + public static void RedirectedRequest(this ILogger logger, string redirectedUrl) { _redirectedRequest(logger, redirectedUrl, null); diff --git a/src/Middleware/Rewrite/src/RedirectToNonWwwRule.cs b/src/Middleware/Rewrite/src/RedirectToNonWwwRule.cs new file mode 100644 index 0000000000..1c6c0a7fbc --- /dev/null +++ b/src/Middleware/Rewrite/src/RedirectToNonWwwRule.cs @@ -0,0 +1,64 @@ +// 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 Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Rewrite.Logging; + +namespace Microsoft.AspNetCore.Rewrite +{ + internal class RedirectToNonWwwRule : IRule + { + private const string WwwDot = "www."; + + private readonly string[] _domains; + private readonly int _statusCode; + + public RedirectToNonWwwRule(int statusCode) + { + _statusCode = statusCode; + } + + public RedirectToNonWwwRule(int statusCode, params string[] domains) + { + if (domains == null) + { + throw new ArgumentNullException(nameof(domains)); + } + + if (domains.Length < 1) + { + throw new ArgumentException($"One or more {nameof(domains)} must be provided."); + } + + _domains = domains; + _statusCode = statusCode; + } + + public void ApplyRule(RewriteContext context) + { + var request = context.HttpContext.Request; + + var hostInDomains = RedirectToWwwHelper.IsHostInDomains(request, _domains); + + if (!hostInDomains) + { + context.Result = RuleResult.ContinueRules; + return; + } + + if (!request.Host.Value.StartsWith(WwwDot, StringComparison.OrdinalIgnoreCase)) + { + context.Result = RuleResult.ContinueRules; + return; + } + + RedirectToWwwHelper.SetRedirect( + context, + new HostString(request.Host.Value.Substring(4)), // We verified the hostname begins with "www." already. + _statusCode); + + context.Logger.RedirectedToNonWww(); + } + } +} diff --git a/src/Middleware/Rewrite/src/RedirectToWwwHelper.cs b/src/Middleware/Rewrite/src/RedirectToWwwHelper.cs new file mode 100644 index 0000000000..4550e7ad9d --- /dev/null +++ b/src/Middleware/Rewrite/src/RedirectToWwwHelper.cs @@ -0,0 +1,61 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.Net.Http.Headers; + +namespace Microsoft.AspNetCore.Rewrite +{ + internal static class RedirectToWwwHelper + { + private const string Localhost = "localhost"; + + public static bool IsHostInDomains(HttpRequest request, string[] domains) + { + if (request.Host.Host.Equals(Localhost, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + if (domains != null) + { + var isHostInDomains = false; + + foreach (var domain in domains) + { + if (domain.Equals(request.Host.Host, StringComparison.OrdinalIgnoreCase)) + { + isHostInDomains = true; + break; + } + } + + if (!isHostInDomains) + { + return false; + } + } + + return true; + } + + public static void SetRedirect(RewriteContext context, HostString newHost, int statusCode) + { + var request = context.HttpContext.Request; + var response = context.HttpContext.Response; + + var newUrl = UriHelper.BuildAbsolute( + request.Scheme, + newHost, + request.PathBase, + request.Path, + request.QueryString); + + response.StatusCode = statusCode; + response.Headers[HeaderNames.Location] = newUrl; + context.Result = RuleResult.EndResponse; + } + } +} diff --git a/src/Middleware/Rewrite/src/RedirectToWwwRule.cs b/src/Middleware/Rewrite/src/RedirectToWwwRule.cs index fcf9735aef..f5b715a648 100644 --- a/src/Middleware/Rewrite/src/RedirectToWwwRule.cs +++ b/src/Middleware/Rewrite/src/RedirectToWwwRule.cs @@ -3,16 +3,16 @@ using System; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Rewrite.Logging; -using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Rewrite { internal class RedirectToWwwRule : IRule { - public readonly int _statusCode; - public readonly string[] _domains; + private const string WwwDot = "www."; + + private readonly string[] _domains; + private readonly int _statusCode; public RedirectToWwwRule(int statusCode) { @@ -28,55 +28,36 @@ namespace Microsoft.AspNetCore.Rewrite if (domains.Length < 1) { - throw new ArgumentException(nameof(domains)); + throw new ArgumentException($"One or more {nameof(domains)} must be provided."); } _domains = domains; _statusCode = statusCode; } - public virtual void ApplyRule(RewriteContext context) + public void ApplyRule(RewriteContext context) { var req = context.HttpContext.Request; - if (req.Host.Host.Equals("localhost", StringComparison.OrdinalIgnoreCase)) + var hostInDomains = RedirectToWwwHelper.IsHostInDomains(req, _domains); + + if (!hostInDomains) { context.Result = RuleResult.ContinueRules; return; } - if (req.Host.Value.StartsWith("www.", StringComparison.OrdinalIgnoreCase)) + if (req.Host.Value.StartsWith(WwwDot, StringComparison.OrdinalIgnoreCase)) { context.Result = RuleResult.ContinueRules; return; } - if (_domains != null) - { - var isHostInDomains = false; + RedirectToWwwHelper.SetRedirect( + context, + new HostString($"www.{context.HttpContext.Request.Host.Value}"), + _statusCode); - foreach (var domain in _domains) - { - if (domain.Equals(req.Host.Host, StringComparison.OrdinalIgnoreCase)) - { - isHostInDomains = true; - break; - } - } - - if (!isHostInDomains) - { - context.Result = RuleResult.ContinueRules; - return; - } - } - - var wwwHost = new HostString($"www.{req.Host.Value}"); - var newUrl = UriHelper.BuildAbsolute(req.Scheme, wwwHost, req.PathBase, req.Path, req.QueryString); - var response = context.HttpContext.Response; - response.StatusCode = _statusCode; - response.Headers[HeaderNames.Location] = newUrl; - context.Result = RuleResult.EndResponse; context.Logger.RedirectedToWww(); } } diff --git a/src/Middleware/Rewrite/src/RewriteOptionsExtensions.cs b/src/Middleware/Rewrite/src/RewriteOptionsExtensions.cs index 88b6d783b4..28d2660fae 100644 --- a/src/Middleware/Rewrite/src/RewriteOptionsExtensions.cs +++ b/src/Middleware/Rewrite/src/RewriteOptionsExtensions.cs @@ -179,5 +179,68 @@ namespace Microsoft.AspNetCore.Rewrite options.Rules.Add(new RedirectToWwwRule(statusCode, domains)); return options; } + + /// + /// Permanently redirects the request to the root domain if the request is from the www subdomain. + /// + /// The . + /// + public static RewriteOptions AddRedirectToNonWwwPermanent(this RewriteOptions options) + { + return AddRedirectToNonWww(options, statusCode: StatusCodes.Status308PermanentRedirect); + } + + /// + /// Permanently redirects the request to the root domain if the request is from the www subdomain. + /// + /// The . + /// Limit the rule to apply only on the specified domain(s). + /// + public static RewriteOptions AddRedirectToNonWwwPermanent(this RewriteOptions options, params string[] domains) + { + return AddRedirectToNonWww(options, statusCode: StatusCodes.Status308PermanentRedirect, domains); + } + + /// + /// Redirect the request to the root domain if the incoming request is from the www subdomain. + /// + /// The . + public static RewriteOptions AddRedirectToNonWww(this RewriteOptions options) + { + return AddRedirectToNonWww(options, statusCode: StatusCodes.Status307TemporaryRedirect); + } + + /// + /// Redirect the request to the root domain if the incoming request is from the www subdomain. + /// + /// The . + /// Limit the rule to apply only on the specified domain(s). + public static RewriteOptions AddRedirectToNonWww(this RewriteOptions options, params string[] domains) + { + return AddRedirectToNonWww(options, statusCode: StatusCodes.Status307TemporaryRedirect, domains); + } + + /// + /// Redirect the request to the root domain if the incoming request is from the www subdomain. + /// + /// The . + /// The status code to add to the response. + public static RewriteOptions AddRedirectToNonWww(this RewriteOptions options, int statusCode) + { + options.Rules.Add(new RedirectToNonWwwRule(statusCode)); + return options; + } + + /// + /// Redirect the request to the root domain if the incoming request is from the www subdomain. + /// + /// The . + /// The status code to add to the response. + /// Limit the rule to apply only on the specified domain(s). + public static RewriteOptions AddRedirectToNonWww(this RewriteOptions options, int statusCode, params string[] domains) + { + options.Rules.Add(new RedirectToNonWwwRule(statusCode, domains)); + return options; + } } } diff --git a/src/Middleware/Rewrite/test/IISUrlRewrite/FileParserTests.cs b/src/Middleware/Rewrite/test/IISUrlRewrite/FileParserTests.cs index 1949e773c8..d5d7323aaa 100644 --- a/src/Middleware/Rewrite/test/IISUrlRewrite/FileParserTests.cs +++ b/src/Middleware/Rewrite/test/IISUrlRewrite/FileParserTests.cs @@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.UrlRewrite - + "; diff --git a/src/Middleware/Rewrite/test/MiddlewareTests.cs b/src/Middleware/Rewrite/test/MiddlewareTests.cs index 0e7eb2c047..e8a4a4aec8 100644 --- a/src/Middleware/Rewrite/test/MiddlewareTests.cs +++ b/src/Middleware/Rewrite/test/MiddlewareTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -232,6 +232,65 @@ namespace Microsoft.AspNetCore.Rewrite.Tests.CodeRules Assert.Null(response.Headers.Location); } + [Theory] + [InlineData(StatusCodes.Status301MovedPermanently)] + [InlineData(StatusCodes.Status302Found)] + [InlineData(StatusCodes.Status307TemporaryRedirect)] + [InlineData(StatusCodes.Status308PermanentRedirect)] + public async Task CheckRedirectToNonWwwWithStatusCode(int statusCode) + { + var options = new RewriteOptions().AddRedirectToNonWww(statusCode: statusCode); + var builder = new WebHostBuilder() + .Configure(app => + { + app.UseRewriter(options); + }); + var server = new TestServer(builder); + + var response = await server.CreateClient().GetAsync(new Uri("https://www.example.com")); + + Assert.Equal("https://example.com/", response.Headers.Location.OriginalString); + Assert.Equal(statusCode, (int)response.StatusCode); + } + + [Theory] + [InlineData("http://www.example.com", "http://example.com/")] + [InlineData("https://www.example.com", "https://example.com/")] + [InlineData("http://www.example.com:8081", "http://example.com:8081/")] + [InlineData("http://www.example.com:8081/example?q=1", "http://example.com:8081/example?q=1")] + public async Task CheckRedirectToNonWww(string requestUri, string redirectUri) + { + var options = new RewriteOptions().AddRedirectToNonWww(); + var builder = new WebHostBuilder() + .Configure(app => + { + app.UseRewriter(options); + }); + var server = new TestServer(builder); + + var response = await server.CreateClient().GetAsync(new Uri(requestUri)); + + Assert.Equal(redirectUri, response.Headers.Location.OriginalString); + Assert.Equal(StatusCodes.Status307TemporaryRedirect, (int)response.StatusCode); + } + + [Fact] + public async Task CheckPermanentRedirectToNonWww() + { + var options = new RewriteOptions().AddRedirectToNonWwwPermanent(); + var builder = new WebHostBuilder() + .Configure(app => + { + app.UseRewriter(options); + }); + var server = new TestServer(builder); + + var response = await server.CreateClient().GetAsync(new Uri("https://www.example.com")); + + Assert.Equal("https://example.com/", response.Headers.Location.OriginalString); + Assert.Equal(StatusCodes.Status308PermanentRedirect, (int)response.StatusCode); + } + [Fact] public async Task CheckIfEmptyStringRedirectCorrectly() { diff --git a/src/Middleware/Session/ref/Microsoft.AspNetCore.Session.netcoreapp.cs b/src/Middleware/Session/ref/Microsoft.AspNetCore.Session.netcoreapp.cs index 241931a4b9..88eb6036ce 100644 --- a/src/Middleware/Session/ref/Microsoft.AspNetCore.Session.netcoreapp.cs +++ b/src/Middleware/Session/ref/Microsoft.AspNetCore.Session.netcoreapp.cs @@ -12,8 +12,8 @@ namespace Microsoft.AspNetCore.Builder { public SessionOptions() { } public Microsoft.AspNetCore.Http.CookieBuilder Cookie { get { throw null; } set { } } - public System.TimeSpan IdleTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan IOTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan IdleTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan IOTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Session @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Session public partial class SessionFeature : Microsoft.AspNetCore.Http.Features.ISessionFeature { public SessionFeature() { } - public Microsoft.AspNetCore.Http.ISession Session { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.ISession Session { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SessionMiddleware { diff --git a/src/Middleware/Session/src/DistributedSession.cs b/src/Middleware/Session/src/DistributedSession.cs index 76ab3f3cf5..8c8632fc6d 100644 --- a/src/Middleware/Session/src/DistributedSession.cs +++ b/src/Middleware/Session/src/DistributedSession.cs @@ -16,7 +16,6 @@ namespace Microsoft.AspNetCore.Session { public class DistributedSession : ISession { - private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); private const int IdByteCount = 16; private const byte SerializationRevision = 2; @@ -104,7 +103,7 @@ namespace Microsoft.AspNetCore.Session if (IsAvailable && _sessionIdBytes == null) { _sessionIdBytes = new byte[IdByteCount]; - CryptoRandom.GetBytes(_sessionIdBytes); + RandomNumberGenerator.Fill(_sessionIdBytes); } return _sessionIdBytes; } diff --git a/src/Middleware/Session/src/SessionMiddleware.cs b/src/Middleware/Session/src/SessionMiddleware.cs index 8d632c08f9..fd7fd65324 100644 --- a/src/Middleware/Session/src/SessionMiddleware.cs +++ b/src/Middleware/Session/src/SessionMiddleware.cs @@ -20,7 +20,6 @@ namespace Microsoft.AspNetCore.Session /// public class SessionMiddleware { - private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); private const int SessionKeyLength = 36; // "382c74c3-721d-4f34-80e5-57657b6cbc27" private static readonly Func ReturnTrue = () => true; private readonly RequestDelegate _next; @@ -91,7 +90,7 @@ namespace Microsoft.AspNetCore.Session { // No valid cookie, new session. var guidBytes = new byte[16]; - CryptoRandom.GetBytes(guidBytes); + RandomNumberGenerator.Fill(guidBytes); sessionKey = new Guid(guidBytes).ToString(); cookieValue = CookieProtection.Protect(_dataProtector, sessionKey); var establisher = new SessionEstablisher(context, cookieValue, _options); @@ -151,7 +150,7 @@ namespace Microsoft.AspNetCore.Session { establisher.SetCookie(); } - return Task.FromResult(0); + return Task.CompletedTask; } private void SetCookie() diff --git a/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs b/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs index 97f23b740d..a8e1299e60 100644 --- a/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs +++ b/src/Middleware/SpaServices.Extensions/ref/Microsoft.AspNetCore.SpaServices.Extensions.netcoreapp.cs @@ -17,10 +17,10 @@ namespace Microsoft.AspNetCore.Builder public partial class SpaPrerenderingOptions { public SpaPrerenderingOptions() { } - public Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder BootModuleBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string BootModulePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] ExcludeUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action> SupplyData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.SpaServices.Prerendering.ISpaPrerendererBuilder BootModuleBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string BootModulePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] ExcludeUrls { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action> SupplyData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class SpaProxyingExtensions { @@ -40,9 +40,11 @@ namespace Microsoft.AspNetCore.SpaServices { public SpaOptions() { } public Microsoft.AspNetCore.Http.PathString DefaultPage { get { throw null; } set { } } - public Microsoft.AspNetCore.Builder.StaticFileOptions DefaultPageStaticFileOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SourcePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan StartupTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Builder.StaticFileOptions DefaultPageStaticFileOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int DevServerPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PackageManagerCommand { get { throw null; } set { } } + public string SourcePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan StartupTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.SpaServices.AngularCli @@ -83,7 +85,7 @@ namespace Microsoft.AspNetCore.SpaServices.StaticFiles public partial class SpaStaticFilesOptions { public SpaStaticFilesOptions() { } - public string RootPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RootPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs index fa3e9cc449..24f0ba430f 100644 --- a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs +++ b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli { private static TimeSpan RegexMatchTimeout = TimeSpan.FromSeconds(5); // This is a development-time only feature, so a very long timeout is fine - private readonly string _npmScriptName; + private readonly string _scriptName; /// /// Constructs an instance of . @@ -35,12 +35,13 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli throw new ArgumentException("Cannot be null or empty.", nameof(npmScript)); } - _npmScriptName = npmScript; + _scriptName = npmScript; } /// public async Task Build(ISpaBuilder spaBuilder) { + var pkgManagerCommand = spaBuilder.Options.PackageManagerCommand; var sourcePath = spaBuilder.Options.SourcePath; if (string.IsNullOrEmpty(sourcePath)) { @@ -50,32 +51,33 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli var logger = LoggerFinder.GetOrCreateLogger( spaBuilder.ApplicationBuilder, nameof(AngularCliBuilder)); - var npmScriptRunner = new NpmScriptRunner( + var scriptRunner = new NodeScriptRunner( sourcePath, - _npmScriptName, + _scriptName, "--watch", - null); - npmScriptRunner.AttachToLogger(logger); + null, + pkgManagerCommand); + scriptRunner.AttachToLogger(logger); - using (var stdOutReader = new EventedStreamStringReader(npmScriptRunner.StdOut)) - using (var stdErrReader = new EventedStreamStringReader(npmScriptRunner.StdErr)) + using (var stdOutReader = new EventedStreamStringReader(scriptRunner.StdOut)) + using (var stdErrReader = new EventedStreamStringReader(scriptRunner.StdErr)) { try { - await npmScriptRunner.StdOut.WaitForMatch( + await scriptRunner.StdOut.WaitForMatch( new Regex("Date", RegexOptions.None, RegexMatchTimeout)); } catch (EndOfStreamException ex) { throw new InvalidOperationException( - $"The NPM script '{_npmScriptName}' exited without indicating success.\n" + + $"The {pkgManagerCommand} script '{_scriptName}' exited without indicating success.\n" + $"Output was: {stdOutReader.ReadAsString()}\n" + $"Error output was: {stdErrReader.ReadAsString()}", ex); } catch (OperationCanceledException ex) { throw new InvalidOperationException( - $"The NPM script '{_npmScriptName}' timed out without indicating success. " + + $"The {pkgManagerCommand} script '{_scriptName}' timed out without indicating success. " + $"Output was: {stdOutReader.ReadAsString()}\n" + $"Error output was: {stdErrReader.ReadAsString()}", ex); } diff --git a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs index 9090f7738b..ede248601d 100644 --- a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs +++ b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs @@ -23,23 +23,25 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli public static void Attach( ISpaBuilder spaBuilder, - string npmScriptName) + string scriptName) { + var pkgManagerCommand = spaBuilder.Options.PackageManagerCommand; var sourcePath = spaBuilder.Options.SourcePath; + var devServerPort = spaBuilder.Options.DevServerPort; if (string.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Cannot be null or empty", nameof(sourcePath)); } - if (string.IsNullOrEmpty(npmScriptName)) + if (string.IsNullOrEmpty(scriptName)) { - throw new ArgumentException("Cannot be null or empty", nameof(npmScriptName)); + throw new ArgumentException("Cannot be null or empty", nameof(scriptName)); } // Start Angular CLI and attach to middleware pipeline var appBuilder = spaBuilder.ApplicationBuilder; var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName); - var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, npmScriptName, logger); + var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, scriptName, pkgManagerCommand, devServerPort, logger); // Everything we proxy is hardcoded to target http://localhost because: // - the requests are always from the local machine (we're not accepting remote @@ -56,33 +58,36 @@ namespace Microsoft.AspNetCore.SpaServices.AngularCli var timeout = spaBuilder.Options.StartupTimeout; return targetUriTask.WithTimeout(timeout, $"The Angular CLI process did not start listening for requests " + - $"within the timeout period of {timeout.Seconds} seconds. " + + $"within the timeout period of {timeout.TotalSeconds} seconds. " + $"Check the log output for error information."); }); } private static async Task StartAngularCliServerAsync( - string sourcePath, string npmScriptName, ILogger logger) + string sourcePath, string scriptName, string pkgManagerCommand, int portNumber, ILogger logger) { - var portNumber = TcpPortFinder.FindAvailablePort(); + if (portNumber == default(int)) + { + portNumber = TcpPortFinder.FindAvailablePort(); + } logger.LogInformation($"Starting @angular/cli on port {portNumber}..."); - var npmScriptRunner = new NpmScriptRunner( - sourcePath, npmScriptName, $"--port {portNumber}", null); - npmScriptRunner.AttachToLogger(logger); + var scriptRunner = new NodeScriptRunner( + sourcePath, scriptName, $"--port {portNumber}", null, pkgManagerCommand); + scriptRunner.AttachToLogger(logger); Match openBrowserLine; - using (var stdErrReader = new EventedStreamStringReader(npmScriptRunner.StdErr)) + using (var stdErrReader = new EventedStreamStringReader(scriptRunner.StdErr)) { try { - openBrowserLine = await npmScriptRunner.StdOut.WaitForMatch( + openBrowserLine = await scriptRunner.StdOut.WaitForMatch( new Regex("open your browser on (http\\S+)", RegexOptions.None, RegexMatchTimeout)); } catch (EndOfStreamException ex) { throw new InvalidOperationException( - $"The NPM script '{npmScriptName}' exited without indicating that the " + + $"The {pkgManagerCommand} script '{scriptName}' exited without indicating that the " + $"Angular CLI was listening for requests. The error output was: " + $"{stdErrReader.ReadAsString()}", ex); } diff --git a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs index 28e63c8e35..8f8176447b 100644 --- a/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs +++ b/src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.Builder; diff --git a/src/Middleware/SpaServices.Extensions/src/Npm/NpmScriptRunner.cs b/src/Middleware/SpaServices.Extensions/src/Npm/NodeScriptRunner.cs similarity index 77% rename from src/Middleware/SpaServices.Extensions/src/Npm/NpmScriptRunner.cs rename to src/Middleware/SpaServices.Extensions/src/Npm/NodeScriptRunner.cs index 378ec5f9fa..f08abeb19c 100644 --- a/src/Middleware/SpaServices.Extensions/src/Npm/NpmScriptRunner.cs +++ b/src/Middleware/SpaServices.Extensions/src/Npm/NodeScriptRunner.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.Extensions.Logging; @@ -16,14 +16,14 @@ namespace Microsoft.AspNetCore.NodeServices.Npm /// Executes the script entries defined in a package.json file, /// capturing any output written to stdio. /// - internal class NpmScriptRunner + internal class NodeScriptRunner { public EventedStreamReader StdOut { get; } public EventedStreamReader StdErr { get; } private static Regex AnsiColorRegex = new Regex("\x001b\\[[0-9;]*m", RegexOptions.None, TimeSpan.FromSeconds(1)); - public NpmScriptRunner(string workingDirectory, string scriptName, string arguments, IDictionary envVars) + public NodeScriptRunner(string workingDirectory, string scriptName, string arguments, IDictionary envVars, string pkgManagerCommand) { if (string.IsNullOrEmpty(workingDirectory)) { @@ -35,18 +35,23 @@ namespace Microsoft.AspNetCore.NodeServices.Npm throw new ArgumentException("Cannot be null or empty.", nameof(scriptName)); } - var npmExe = "npm"; + if (string.IsNullOrEmpty(pkgManagerCommand)) + { + throw new ArgumentException("Cannot be null or empty.", nameof(pkgManagerCommand)); + } + + var exeToRun = pkgManagerCommand; var completeArguments = $"run {scriptName} -- {arguments ?? string.Empty}"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - // On Windows, the NPM executable is a .cmd file, so it can't be executed + // On Windows, the node executable is a .cmd file, so it can't be executed // directly (except with UseShellExecute=true, but that's no good, because // it prevents capturing stdio). So we need to invoke it via "cmd /c". - npmExe = "cmd"; - completeArguments = $"/c npm {completeArguments}"; + exeToRun = "cmd"; + completeArguments = $"/c {pkgManagerCommand} {completeArguments}"; } - var processStartInfo = new ProcessStartInfo(npmExe) + var processStartInfo = new ProcessStartInfo(exeToRun) { Arguments = completeArguments, UseShellExecute = false, @@ -64,19 +69,19 @@ namespace Microsoft.AspNetCore.NodeServices.Npm } } - var process = LaunchNodeProcess(processStartInfo); + var process = LaunchNodeProcess(processStartInfo, pkgManagerCommand); StdOut = new EventedStreamReader(process.StandardOutput); StdErr = new EventedStreamReader(process.StandardError); } public void AttachToLogger(ILogger logger) { - // When the NPM task emits complete lines, pass them through to the real logger + // When the node task emits complete lines, pass them through to the real logger StdOut.OnReceivedLine += line => { if (!string.IsNullOrWhiteSpace(line)) { - // NPM tasks commonly emit ANSI colors, but it wouldn't make sense to forward + // Node tasks commonly emit ANSI colors, but it wouldn't make sense to forward // those to loggers (because a logger isn't necessarily any kind of terminal) logger.LogInformation(StripAnsiColors(line)); } @@ -106,7 +111,7 @@ namespace Microsoft.AspNetCore.NodeServices.Npm private static string StripAnsiColors(string line) => AnsiColorRegex.Replace(line, string.Empty); - private static Process LaunchNodeProcess(ProcessStartInfo startInfo) + private static Process LaunchNodeProcess(ProcessStartInfo startInfo, string commandName) { try { @@ -119,8 +124,8 @@ namespace Microsoft.AspNetCore.NodeServices.Npm } catch (Exception ex) { - var message = $"Failed to start 'npm'. To resolve this:.\n\n" - + "[1] Ensure that 'npm' is installed and can be found in one of the PATH directories.\n" + var message = $"Failed to start '{commandName}'. To resolve this:.\n\n" + + $"[1] Ensure that '{commandName}' is installed and can be found in one of the PATH directories.\n" + $" Current PATH enviroment variable is: { Environment.GetEnvironmentVariable("PATH") }\n" + " Make sure the executable is in one of those directories, or update your PATH.\n\n" + "[2] See the InnerException for further details of the cause."; diff --git a/src/Middleware/SpaServices.Extensions/src/Proxying/SpaProxy.cs b/src/Middleware/SpaServices.Extensions/src/Proxying/SpaProxy.cs index 91c6b72f96..04d7e697a1 100644 --- a/src/Middleware/SpaServices.Extensions/src/Proxying/SpaProxy.cs +++ b/src/Middleware/SpaServices.Extensions/src/Proxying/SpaProxy.cs @@ -22,6 +22,9 @@ namespace Microsoft.AspNetCore.SpaServices.Extensions.Proxy private const int DefaultWebSocketBufferSize = 4096; private const int StreamCopyBufferSize = 81920; + // https://github.com/dotnet/aspnetcore/issues/16797 + private static readonly string[] NotForwardedHttpHeaders = new[] { "Connection" }; + // Don't forward User-Agent/Accept because of https://github.com/aspnet/JavaScriptServices/issues/1469 // Others just aren't applicable in proxy scenarios private static readonly string[] NotForwardedWebSocketHeaders = new[] { "Accept", "Connection", "Host", "User-Agent", "Upgrade", "Sec-WebSocket-Key", "Sec-WebSocket-Version" }; @@ -132,6 +135,11 @@ namespace Microsoft.AspNetCore.SpaServices.Extensions.Proxy // Copy the request headers foreach (var header in request.Headers) { + if (NotForwardedHttpHeaders.Contains(header.Key, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null) { requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()); diff --git a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs index 78a7b4f03f..b4cb361b54 100644 --- a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs +++ b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs @@ -22,23 +22,25 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer public static void Attach( ISpaBuilder spaBuilder, - string npmScriptName) + string scriptName) { + var pkgManagerCommand = spaBuilder.Options.PackageManagerCommand; var sourcePath = spaBuilder.Options.SourcePath; + var devServerPort = spaBuilder.Options.DevServerPort; if (string.IsNullOrEmpty(sourcePath)) { throw new ArgumentException("Cannot be null or empty", nameof(sourcePath)); } - if (string.IsNullOrEmpty(npmScriptName)) + if (string.IsNullOrEmpty(scriptName)) { - throw new ArgumentException("Cannot be null or empty", nameof(npmScriptName)); + throw new ArgumentException("Cannot be null or empty", nameof(scriptName)); } // Start create-react-app and attach to middleware pipeline var appBuilder = spaBuilder.ApplicationBuilder; var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName); - var portTask = StartCreateReactAppServerAsync(sourcePath, npmScriptName, logger); + var portTask = StartCreateReactAppServerAsync(sourcePath, scriptName, pkgManagerCommand, devServerPort, logger); // Everything we proxy is hardcoded to target http://localhost because: // - the requests are always from the local machine (we're not accepting remote @@ -61,9 +63,12 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer } private static async Task StartCreateReactAppServerAsync( - string sourcePath, string npmScriptName, ILogger logger) + string sourcePath, string scriptName, string pkgManagerCommand, int portNumber, ILogger logger) { - var portNumber = TcpPortFinder.FindAvailablePort(); + if (portNumber == default(int)) + { + portNumber = TcpPortFinder.FindAvailablePort(); + } logger.LogInformation($"Starting create-react-app server on port {portNumber}..."); var envVars = new Dictionary @@ -71,11 +76,11 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer { "PORT", portNumber.ToString() }, { "BROWSER", "none" }, // We don't want create-react-app to open its own extra browser window pointing to the internal dev server port }; - var npmScriptRunner = new NpmScriptRunner( - sourcePath, npmScriptName, null, envVars); - npmScriptRunner.AttachToLogger(logger); + var scriptRunner = new NodeScriptRunner( + sourcePath, scriptName, null, envVars, pkgManagerCommand); + scriptRunner.AttachToLogger(logger); - using (var stdErrReader = new EventedStreamStringReader(npmScriptRunner.StdErr)) + using (var stdErrReader = new EventedStreamStringReader(scriptRunner.StdErr)) { try { @@ -83,13 +88,13 @@ namespace Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer // it doesn't do so until it's finished compiling, and even then only if there were // no compiler warnings. So instead of waiting for that, consider it ready as soon // as it starts listening for requests. - await npmScriptRunner.StdOut.WaitForMatch( + await scriptRunner.StdOut.WaitForMatch( new Regex("Starting the development server", RegexOptions.None, RegexMatchTimeout)); } catch (EndOfStreamException ex) { throw new InvalidOperationException( - $"The NPM script '{npmScriptName}' exited without indicating that the " + + $"The {pkgManagerCommand} script '{scriptName}' exited without indicating that the " + $"create-react-app server was listening for requests. The error output was: " + $"{stdErrReader.ReadAsString()}", ex); } diff --git a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs index f58a6d1a9d..346e839046 100644 --- a/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs +++ b/src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.Builder; diff --git a/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs b/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs index b2823396dc..3b7f4f1a71 100644 --- a/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs +++ b/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs @@ -1,11 +1,10 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.FileProviders; -using System; namespace Microsoft.AspNetCore.SpaServices { @@ -15,6 +14,7 @@ namespace Microsoft.AspNetCore.SpaServices public class SpaOptions { private PathString _defaultPage = "/index.html"; + private string _packageManagerCommand = "npm"; /// /// Constructs a new instance of . @@ -30,8 +30,10 @@ namespace Microsoft.AspNetCore.SpaServices internal SpaOptions(SpaOptions copyFromOptions) { _defaultPage = copyFromOptions.DefaultPage; + _packageManagerCommand = copyFromOptions.PackageManagerCommand; DefaultPageStaticFileOptions = copyFromOptions.DefaultPageStaticFileOptions; SourcePath = copyFromOptions.SourcePath; + DevServerPort = copyFromOptions.DevServerPort; } /// @@ -69,6 +71,31 @@ namespace Microsoft.AspNetCore.SpaServices /// public string SourcePath { get; set; } + /// + /// Controls wether the development server should be used with a dynamic or fixed port. + /// + public int DevServerPort { get; set; } = default(int); + + /// + /// Gets or sets the name of the package manager executible, (e.g npm, + /// yarn) to run the SPA. + /// + /// The default value is 'npm'. + /// + public string PackageManagerCommand + { + get => _packageManagerCommand; + set + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentException($"The value for {nameof(PackageManagerCommand)} cannot be null or empty."); + } + + _packageManagerCommand = value; + } + } + /// /// Gets or sets the maximum duration that a request will wait for the SPA /// to become ready to serve to the client. diff --git a/src/Middleware/SpaServices.Extensions/src/Util/EventedStreamReader.cs b/src/Middleware/SpaServices.Extensions/src/Util/EventedStreamReader.cs index 95e018a590..aafd630853 100644 --- a/src/Middleware/SpaServices.Extensions/src/Util/EventedStreamReader.cs +++ b/src/Middleware/SpaServices.Extensions/src/Util/EventedStreamReader.cs @@ -83,23 +83,35 @@ namespace Microsoft.AspNetCore.NodeServices.Util var chunkLength = await _streamReader.ReadAsync(buf, 0, buf.Length); if (chunkLength == 0) { + if (_linesBuffer.Length > 0) + { + OnCompleteLine(_linesBuffer.ToString()); + _linesBuffer.Clear(); + } + OnClosed(); break; } OnChunk(new ArraySegment(buf, 0, chunkLength)); - var lineBreakPos = Array.IndexOf(buf, '\n', 0, chunkLength); - if (lineBreakPos < 0) + int lineBreakPos = -1; + int startPos = 0; + + // get all the newlines + while ((lineBreakPos = Array.IndexOf(buf, '\n', startPos, chunkLength - startPos)) >= 0 && startPos < chunkLength) { - _linesBuffer.Append(buf, 0, chunkLength); - } - else - { - _linesBuffer.Append(buf, 0, lineBreakPos + 1); + var length = (lineBreakPos + 1) - startPos; + _linesBuffer.Append(buf, startPos, length); OnCompleteLine(_linesBuffer.ToString()); _linesBuffer.Clear(); - _linesBuffer.Append(buf, lineBreakPos + 1, chunkLength - (lineBreakPos + 1)); + startPos = lineBreakPos + 1; + } + + // get the rest + if (lineBreakPos < 0 && startPos < chunkLength) + { + _linesBuffer.Append(buf, startPos, chunkLength); } } } diff --git a/src/Middleware/SpaServices/ref/Microsoft.AspNetCore.SpaServices.netcoreapp.cs b/src/Middleware/SpaServices/ref/Microsoft.AspNetCore.SpaServices.netcoreapp.cs index 1b9fa3ae00..21fae17651 100644 --- a/src/Middleware/SpaServices/ref/Microsoft.AspNetCore.SpaServices.netcoreapp.cs +++ b/src/Middleware/SpaServices/ref/Microsoft.AspNetCore.SpaServices.netcoreapp.cs @@ -27,8 +27,8 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering public partial class JavaScriptModuleExport { public JavaScriptModuleExport(string moduleName) { } - public string ExportName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ModuleName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ExportName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ModuleName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.ObsoleteAttribute("Use Microsoft.AspNetCore.SpaServices.Extensions")] public static partial class Prerenderer @@ -42,16 +42,16 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering { public PrerenderTagHelper(System.IServiceProvider serviceProvider) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-prerender-data")] - public object CustomDataParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object CustomDataParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-prerender-export")] - public string ExportName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ExportName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-prerender-module")] - public string ModuleName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ModuleName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-prerender-timeout")] - public int TimeoutMillisecondsParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int TimeoutMillisecondsParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -59,10 +59,10 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering public partial class RenderToStringResult { public RenderToStringResult() { } - public Newtonsoft.Json.Linq.JObject Globals { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Html { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RedirectUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Newtonsoft.Json.Linq.JObject Globals { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Html { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RedirectUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string CreateGlobalsAssignmentScript() { throw null; } } } @@ -72,15 +72,15 @@ namespace Microsoft.AspNetCore.SpaServices.Webpack public partial class WebpackDevMiddlewareOptions { public WebpackDevMiddlewareOptions() { } - public string ConfigFile { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary EnvironmentVariables { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object EnvParam { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HotModuleReplacement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary HotModuleReplacementClientOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HotModuleReplacementEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int HotModuleReplacementServerPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ProjectPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ReactHotModuleReplacement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ConfigFile { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary EnvironmentVariables { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object EnvParam { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HotModuleReplacement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary HotModuleReplacementClientOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HotModuleReplacementEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int HotModuleReplacementServerPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ProjectPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ReactHotModuleReplacement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock b/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock index ede57b1546..3727098d92 100644 --- a/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock +++ b/src/Middleware/SpaServices/src/npm/aspnet-webpack/yarn.lock @@ -2,71 +2,251 @@ # yarn lockfile v1 +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + "@types/connect@^3.4.30": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.31.tgz#1f92d6b117ecc05076c49ecd024f7976e528bad9" - integrity sha512-OPSxsP6XqA3984KWDUXq/u05Hu8VWa/2rUVlw/aDUOx87BptIep6xb3NdCxCpKLfLdjZcCE5jR+gouTul3gjdA== + version "3.4.32" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.32.tgz#aa0e9616b9435ccad02bc52b5b454ffc2c70ba28" + integrity sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg== dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^6.0.42": - version "6.0.96" - resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.96.tgz#7bf0bf40d6ce51e93762cc47d010c8cc5ebb2179" - integrity sha512-fsOOY6tMQ3jCB2wD51XFDmmpgm4wVKkJECdcVRqapbJEa7awJDcr+SaH8toz+4r4KW8YQ3M7ybXMoSDo1QGewA== +"@types/node@*": + version "12.12.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.14.tgz#1c1d6e3c75dba466e0326948d56e8bd72a1903d2" + integrity sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA== + +"@types/node@^6.0.42": + version "6.14.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.14.9.tgz#733583e21ef0eab85a9737dfafbaa66345a92ef0" + integrity sha512-leP/gxHunuazPdZaCvsCefPQxinqUDsCxCR5xaDUrY2MkYxQRFZZwU5e7GojyYsGB7QVtCi7iVEl/hoFXQYc+w== + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/tapable@*": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd" - integrity sha512-42zEJkBpNfMEAvWR5WlwtTH22oDzcMjFsL9gDGExwF8X8WvAiw7Vwop7hPw03QT8TKfec83LwbHj6SvpqM4ELQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" + integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== "@types/uglify-js@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.2.tgz#f30c75458d18e8ee885c792c04adcb78a13bc286" - integrity sha512-o8hU2+4xsyGC27Vujoklvxl88Ew5zmJuTBYMX1Uro2rYUt4HEFJKL6fuq8aGykvS+ssIsIzerWWP2DRxonownQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082" + integrity sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ== dependencies: source-map "^0.6.1" -"@types/webpack@^4.1.3": - version "4.1.3" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.1.3.tgz#1cbb3fceb275590b63addf7cfb1534fda7e645a1" - integrity sha512-NoGVTCumOsyFfuy3934f3ktiJi+wcXHJFxT47tby3iCpuo6M/WjFA9VqT5bYO+FE46i3R0N00RpJX75HxHKDaQ== +"@types/webpack-sources@*": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.5.tgz#be47c10f783d3d6efe1471ff7f042611bd464a92" + integrity sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w== dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.6.1" + +"@types/webpack@^4.1.3": + version "4.41.0" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.0.tgz#b813a044d8b0dec7dfcd7622fdbe327bde06eb9a" + integrity sha512-tWkdf9nO0zFgAY/EumUKwrDUhraHKDqCPhwfFR/R8l0qnPdgb9le0Gzhvb7uzVpouuDGBgiE//ZdY+5jcZy2TA== + dependencies: + "@types/anymatch" "*" "@types/node" "*" "@types/tapable" "*" "@types/uglify-js" "*" + "@types/webpack-sources" "*" source-map "^0.6.0" +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn-dynamic-import@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" - integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== - dependencies: - acorn "^5.0.0" +acorn@^6.2.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" + integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== -acorn@^5.0.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" - integrity sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ== +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" - integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.0.tgz#4c8affdf80887d8f132c9c52ab8a2dc4d0b7b24c" - integrity sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA== +ajv@^6.1.0, ajv@^6.10.2: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - uri-js "^4.2.1" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" ansi-regex@^2.0.0: version "2.1.1" @@ -129,10 +309,11 @@ asn1.js@^4.0.0: minimalistic-assert "^1.0.0" assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== dependencies: + object-assign "^4.1.1" util "0.10.3" assign-symbols@^1.0.0: @@ -140,15 +321,15 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== atob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" - integrity sha1-ri1acpR38onWDdf5amMUoi3Wwio= + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== balanced-match@^1.0.0: version "1.0.0" @@ -156,9 +337,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== base@^0.11.1: version "0.11.2" @@ -173,20 +354,20 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -big.js@^3.1.3: - version "3.2.0" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" - integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" - integrity sha1-RqoXUftqL5PuXmibsQh9SxTGwgU= + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== -bluebird@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" @@ -194,14 +375,14 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" - integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI= + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.0, braces@^2.3.1: +braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== @@ -244,13 +425,14 @@ browserify-cipher@^1.0.0: evp_bytestokey "^1.0.0" browserify-des@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.1.tgz#3343124db6d7ad53e26a8826318712bdc8450f9c" - integrity sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" des.js "^1.0.0" inherits "^2.0.1" + safe-buffer "^5.1.2" browserify-rsa@^4.0.0: version "4.0.1" @@ -281,9 +463,9 @@ browserify-zlib@^0.2.0: pako "~1.0.5" buffer-from@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" - integrity sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== buffer-xor@^1.0.3: version "1.0.3" @@ -291,9 +473,9 @@ buffer-xor@^1.0.3: integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -304,23 +486,25 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -cacache@^10.0.4: - version "10.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" - integrity sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA== +cacache@^12.0.2: + version "12.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" + integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== dependencies: - bluebird "^3.5.1" - chownr "^1.0.1" - glob "^7.1.2" - graceful-fs "^4.1.11" - lru-cache "^4.1.1" - mississippi "^2.0.0" + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" mkdirp "^0.5.1" move-concurrently "^1.0.1" promise-inflight "^1.0.1" - rimraf "^2.6.2" - ssri "^5.2.4" - unique-filename "^1.1.0" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" y18n "^4.0.0" cache-base@^1.0.1: @@ -339,38 +523,35 @@ cache-base@^1.0.1: unset-value "^1.0.0" chokidar@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176" - integrity sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg== + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" - async-each "^1.0.0" - braces "^2.3.0" + async-each "^1.0.1" + braces "^2.3.2" glob-parent "^3.1.0" - inherits "^2.0.1" + inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" - normalize-path "^2.1.1" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" - upath "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.1.2" - -chownr@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" - integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= + fsevents "^1.2.7" chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== -chrome-trace-event@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz#d395af2d31c87b90a716c831fe326f69768ec084" - integrity sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A== +chrome-trace-event@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -403,10 +584,10 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commondir@^1.0.1: version "1.0.1" @@ -414,9 +595,9 @@ commondir@^1.0.1: integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== concat-map@0.0.1: version "0.0.1" @@ -434,21 +615,19 @@ concat-stream@^1.5.0: typedarray "^0.0.6" connect@^3.4.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.5.tgz#fb8dde7ba0763877d0ec9df9dac0b4b40e72c7da" - integrity sha1-+43ee6B2OHfQ7J352sC0tA5yx9o= + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== dependencies: debug "2.6.9" - finalhandler "1.0.6" - parseurl "~1.3.2" + finalhandler "1.1.2" + parseurl "~1.3.3" utils-merge "1.0.1" console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= - dependencies: - date-now "^0.1.4" + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" @@ -530,23 +709,25 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= - -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -585,9 +766,9 @@ delegates@^1.0.0: integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -612,9 +793,9 @@ domain-browser@^1.1.1: integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== duplexify@^3.4.2, duplexify@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" - integrity sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ== + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== dependencies: end-of-stream "^1.0.0" inherits "^2.0.1" @@ -627,9 +808,9 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= elliptic@^6.0.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" - integrity sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8= + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -644,35 +825,28 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= -encodeurl@~1.0.1: +encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enhanced-resolve@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" - integrity sha512-jox/62b2GofV1qTUQTMPEJSDIGycS43evqYzD/KVtEb9OCoki9cnacUPxCrZa7JfPzZSYOCZhu9O9luaMxAX8g== +enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== dependencies: graceful-fs "^4.1.2" - memory-fs "^0.4.0" + memory-fs "^0.5.0" tapable "^1.0.0" -errno@^0.1.3: - version "0.1.6" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026" - integrity sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw== - dependencies: - prr "~1.0.1" - -errno@~0.1.7: +errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== @@ -689,10 +863,10 @@ escape-html@~1.0.3: resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -eslint-scope@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== dependencies: esrecurse "^4.1.0" estraverse "^4.1.1" @@ -705,14 +879,14 @@ esrecurse@^4.1.0: estraverse "^4.1.0" estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -events@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -774,6 +948,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= +figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -784,42 +963,42 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" -finalhandler@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.6.tgz#007aea33d1a4d3e42017f624848ad58d212f814f" - integrity sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8= +finalhandler@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== dependencies: debug "2.6.9" - encodeurl "~1.0.1" + encodeurl "~1.0.2" escape-html "~1.0.3" on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.3.1" + parseurl "~1.3.3" + statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" - integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== dependencies: commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^2.0.0" + make-dir "^2.0.0" + pkg-dir "^3.0.0" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: - locate-path "^2.0.0" + locate-path "^3.0.0" flush-write-stream@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" - integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== dependencies: - inherits "^2.0.1" - readable-stream "^2.0.4" + inherits "^2.0.3" + readable-stream "^2.3.6" for-in@^1.0.2: version "1.0.2" @@ -842,11 +1021,11 @@ from2@^2.1.0: readable-stream "^2.0.0" fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: - minipass "^2.2.1" + minipass "^2.6.0" fs-write-stream-atomic@^1.0.8: version "1.0.10" @@ -863,13 +1042,13 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.1.2: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" - integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== +fsevents@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" + nan "^2.12.1" + node-pre-gyp "^0.12.0" gauge@~2.7.3: version "2.7.4" @@ -898,10 +1077,10 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.5, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== +glob@^7.1.3, glob@^7.1.4: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -910,22 +1089,10 @@ glob@^7.0.5, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== has-unicode@^2.0.0: version "2.0.1" @@ -972,12 +1139,12 @@ hash-base@^3.0.0: safe-buffer "^5.0.1" hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" - minimalistic-assert "^1.0.0" + minimalistic-assert "^1.0.1" hmac-drbg@^1.0.0: version "1.0.1" @@ -1001,9 +1168,9 @@ iconv-lite@^0.4.4: safer-buffer ">= 2.1.2 < 3" ieee754@^1.1.4: - version "1.1.11" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.11.tgz#c16384ffe00f5b7835824e67b6f2bd44a5229455" - integrity sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg== + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== iferr@^0.1.5: version "0.1.5" @@ -1011,9 +1178,9 @@ iferr@^0.1.5: integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== dependencies: minimatch "^3.0.4" @@ -1022,10 +1189,10 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== inflight@^1.0.4: version "1.0.6" @@ -1036,15 +1203,20 @@ inflight@^1.0.4: wrappy "1" inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -1145,9 +1317,9 @@ is-glob@^3.1.0: is-extglob "^2.1.0" is-glob@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" - integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" @@ -1158,19 +1330,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - -is-odd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" - integrity sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ== - dependencies: - is-number "^4.0.0" - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== @@ -1182,6 +1342,11 @@ is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1199,15 +1364,22 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json5@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" @@ -1233,42 +1405,47 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -loader-runner@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" - integrity sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI= +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= +loader-utils@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== dependencies: - big.js "^3.1.3" + big.js "^5.2.2" emojis-list "^2.0.0" - json5 "^0.5.0" + json5 "^1.0.1" -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: - p-locate "^2.0.0" + p-locate "^3.0.0" path-exists "^3.0.0" -lru-cache@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" + yallist "^3.0.2" -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== dependencies: - pify "^3.0.0" + pify "^4.0.1" + semver "^5.6.0" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== map-cache@^0.2.2: version "0.2.2" @@ -1283,12 +1460,13 @@ map-visit@^1.0.0: object-visit "^1.0.0" md5.js@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" - integrity sha1-6b296UogpawYsENA/Fdk1bCdkB0= + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" inherits "^2.0.1" + safe-buffer "^5.1.2" memory-fs@^0.3.0: version "0.3.0" @@ -1298,7 +1476,7 @@ memory-fs@^0.3.0: errno "^0.1.3" readable-stream "^2.0.1" -memory-fs@^0.4.0, memory-fs@~0.4.1: +memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -1306,7 +1484,15 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -micromatch@^3.1.4, micromatch@^3.1.8: +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -1333,7 +1519,7 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -minimalistic-assert@^1.0.0: +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== @@ -1343,7 +1529,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -1360,25 +1546,25 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" -minizlib@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== dependencies: - minipass "^2.2.1" + minipass "^2.9.0" -mississippi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" - integrity sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw== +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== dependencies: concat-stream "^1.5.0" duplexify "^3.4.2" @@ -1386,20 +1572,20 @@ mississippi@^2.0.0: flush-write-stream "^1.0.0" from2 "^2.1.0" parallel-transform "^1.1.0" - pump "^2.0.1" + pump "^3.0.0" pumpify "^1.3.3" stream-each "^1.1.0" through2 "^2.0.0" mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -1423,22 +1609,26 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -nan@^2.9.2: - version "2.12.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== nanomatch@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" - integrity sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA== + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" define-property "^2.0.2" extend-shallow "^3.0.2" fragment-cache "^0.2.1" - is-odd "^2.0.0" is-windows "^1.0.2" kind-of "^6.0.2" object.pick "^1.3.0" @@ -1447,23 +1637,23 @@ nanomatch@^1.2.9: to-regex "^3.0.1" needle@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" - integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== dependencies: - debug "^2.1.2" + debug "^3.2.6" iconv-lite "^0.4.4" sax "^1.2.4" -neo-async@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" - integrity sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA== +neo-async@^2.5.0, neo-async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== -node-libs-browser@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" - integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== dependencies: assert "^1.1.1" browserify-zlib "^0.2.0" @@ -1472,10 +1662,10 @@ node-libs-browser@^2.0.0: constants-browserify "^1.0.0" crypto-browserify "^3.11.0" domain-browser "^1.1.1" - events "^1.0.0" + events "^3.0.0" https-browserify "^1.0.0" os-browserify "^0.3.0" - path-browserify "0.0.0" + path-browserify "0.0.1" process "^0.11.10" punycode "^1.2.4" querystring-es3 "^0.2.0" @@ -1486,13 +1676,13 @@ node-libs-browser@^2.0.0: timers-browserify "^2.0.4" tty-browserify "0.0.0" url "^0.11.0" - util "^0.10.3" - vm-browserify "0.0.4" + util "^0.11.0" + vm-browserify "^1.0.1" -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== dependencies: detect-libc "^1.0.2" mkdirp "^0.5.1" @@ -1520,15 +1710,20 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== npm-packlist@^1.1.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.3.0.tgz#7f01e8e44408341379ca98cfd756e7b29bd2626c" - integrity sha512-qPBc6CnxEzpOcc4bjoIBJbYdy0D/LFFPUdxvfwor4/w3vxeE0h6TiOVurCEPpQ6trjN77u/ShyfeJGsbAfB3dA== + version "1.4.6" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" + integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -1548,7 +1743,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -object-assign@^4.1.0: +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -1613,64 +1808,65 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -p-limit@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" - integrity sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng== +p-limit@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: - p-try "^1.0.0" + p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: - p-limit "^1.1.0" + p-limit "^2.0.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" - integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== dependencies: - cyclist "~0.2.2" + cyclist "^1.0.1" inherits "^2.0.3" readable-stream "^2.1.5" parse-asn1@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" - integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" create-hash "^1.1.0" evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" -parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" - integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== path-dirname@^1.0.0: version "1.0.2" @@ -1688,9 +1884,9 @@ path-is-absolute@^1.0.0: integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= pbkdf2@^3.0.3: - version "3.0.16" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" - integrity sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA== + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -1698,32 +1894,27 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== dependencies: - find-up "^2.1.0" + find-up "^3.0.0" posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= - process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@^0.11.10: version "0.11.10" @@ -1740,23 +1931,19 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - public-encrypt@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" - integrity sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q== + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" browserify-rsa "^4.0.0" create-hash "^1.1.0" parse-asn1 "^5.0.0" randombytes "^2.0.1" + safe-buffer "^5.1.2" -pump@^2.0.0, pump@^2.0.1: +pump@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== @@ -1764,6 +1951,14 @@ pump@^2.0.0, pump@^2.0.1: end-of-stream "^1.1.0" once "^1.3.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pumpify@^1.3.3: version "1.5.1" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" @@ -1799,9 +1994,9 @@ querystring@0.2.0: integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" - integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" @@ -1823,20 +2018,7 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" - integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.1" - string_decoder "~1.0.3" - util-deprecate "~1.0.1" - -readable-stream@^2.0.6, readable-stream@^2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -1849,15 +2031,14 @@ readable-stream@^2.0.6, readable-stream@^2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - integrity sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg= +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" + graceful-fs "^4.1.11" + micromatch "^3.1.10" readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -1873,9 +2054,9 @@ remove-trailing-separator@^1.0.1: integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== repeat-string@^1.6.1: version "1.6.1" @@ -1897,17 +2078,10 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.5.4, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== - dependencies: - glob "^7.0.5" - -rimraf@^2.6.1: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" @@ -1926,12 +2100,12 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== -safe-buffer@^5.1.2: +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -1953,48 +2127,34 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -schema-utils@^0.4.2, schema-utils@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" - integrity sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA== +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== dependencies: ajv "^6.1.0" + ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -semver@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== +semver@^5.3.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -serialize-javascript@^1.4.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" - integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== +serialize-javascript@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" + integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -2050,9 +2210,9 @@ snapdragon@^0.8.1: use "^3.1.0" source-list-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" - integrity sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A== + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: version "0.5.2" @@ -2065,6 +2225,14 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@~0.5.12: + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" @@ -2087,12 +2255,12 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -ssri@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" - integrity sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ== +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== dependencies: - safe-buffer "^5.1.1" + figgy-pudding "^3.5.1" static-extend@^0.1.1: version "0.1.2" @@ -2102,31 +2270,31 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -statuses@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" - integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= +statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= stream-browserify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" - integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" readable-stream "^2.0.2" stream-each@^1.1.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" - integrity sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== dependencies: end-of-stream "^1.1.0" stream-shift "^1.0.0" stream-http@^2.7.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.2.tgz#4126e8c6b107004465918aa2fc35549e77402c87" - integrity sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA== + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" @@ -2156,12 +2324,12 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^1.0.0, string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== +string_decoder@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - safe-buffer "~5.1.0" + safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" @@ -2189,36 +2357,60 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -tapable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" - integrity sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg== +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" + minipass "^2.8.6" + minizlib "^1.2.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" - yallist "^3.0.2" + yallist "^3.0.3" + +terser-webpack-plugin@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz#e23c0d554587d1f473bd0cf68627720e733890a4" + integrity sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.1" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.2.tgz#448fffad0245f4c8a277ce89788b458bfd7706e8" + integrity sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== dependencies: - readable-stream "^2.1.5" + readable-stream "~2.3.6" xtend "~4.0.1" timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== dependencies: setimmediate "^1.0.4" @@ -2252,6 +2444,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +tslib@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -2263,53 +2460,31 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^2.0.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" - integrity sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q= - -uglify-es@^3.3.4: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== - dependencies: - commander "~2.13.0" - source-map "~0.6.1" - -uglifyjs-webpack-plugin@^1.2.4: - version "1.2.5" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz#2ef8387c8f1a903ec5e44fa36f9f3cbdcea67641" - integrity sha512-hIQJ1yxAPhEA2yW/i7Fr+SXZVMp+VEI3d42RTHBgQd2yhp/1UdBcR3QEWPV5ahBxlqQDMEMTuTEvDHSFINfwSw== - dependencies: - cacache "^10.0.4" - find-cache-dir "^1.0.0" - schema-utils "^0.4.5" - serialize-javascript "^1.4.0" - source-map "^0.6.1" - uglify-es "^3.3.4" - webpack-sources "^1.1.0" - worker-farm "^1.5.2" + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" + integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w== union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== dependencies: arr-union "^3.1.0" get-value "^2.0.6" is-extendable "^0.1.1" - set-value "^0.4.3" + set-value "^2.0.1" -unique-filename@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" - integrity sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM= +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== dependencies: unique-slug "^2.0.0" unique-slug@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" - integrity sha1-22Z258fMBimHj/GWCXx4hVrp9Ks= + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== dependencies: imurmurhash "^0.1.4" @@ -2326,12 +2501,12 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -upath@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" - integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -uri-js@^4.2.1: +uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== @@ -2352,37 +2527,40 @@ url@^0.11.0: querystring "0.2.0" use@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" - integrity sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw== - dependencies: - kind-of "^6.0.2" + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@0.10.3, util@^0.10.3: +util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: inherits "2.0.1" +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -vm-browserify@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" - integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= - dependencies: - indexof "0.0.1" +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -watchpack@^1.5.0: +watchpack@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== @@ -2392,42 +2570,46 @@ watchpack@^1.5.0: neo-async "^2.5.0" webpack-node-externals@^1.4.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.6.0.tgz#232c62ec6092b100635a3d29d83c1747128df9bd" - integrity sha1-Iyxi7GCSsQBjWj0p2DwXRxKN+b0= + version "1.7.2" + resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" + integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== -webpack-sources@^1.0.1, webpack-sources@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" - integrity sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw== +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" source-map "~0.6.1" webpack@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.5.0.tgz#1e6f71e148ead02be265ff2879c9cd6bb30b8848" - integrity sha512-6GrZsvQJnG7o7mjbfjp6s5CyMfdopjt1A/X8LcYwceis9ySjqBX6Lusso2wNZ06utHj2ZvfL6L3f7hfgVeJP6g== + version "4.41.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e" + integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A== dependencies: - acorn "^5.0.0" - acorn-dynamic-import "^3.0.0" - ajv "^6.1.0" - ajv-keywords "^3.1.0" - chrome-trace-event "^0.1.1" - enhanced-resolve "^4.0.0" - eslint-scope "^3.7.1" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" - micromatch "^3.1.8" - mkdirp "~0.5.0" - neo-async "^2.5.0" - node-libs-browser "^2.0.0" - schema-utils "^0.4.2" - tapable "^1.0.0" - uglifyjs-webpack-plugin "^1.2.4" - watchpack "^1.5.0" - webpack-sources "^1.0.1" + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.1" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.1" + watchpack "^1.6.0" + webpack-sources "^1.4.1" wide-align@^1.1.0: version "1.1.3" @@ -2436,10 +2618,10 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -worker-farm@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" - integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== dependencies: errno "~0.1.7" @@ -2449,21 +2631,16 @@ wrappy@1: integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= xtend@^4.0.0, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== diff --git a/src/Middleware/SpaServices/src/yarn.lock b/src/Middleware/SpaServices/src/yarn.lock index e4e1d0db4f..78a57b8922 100644 --- a/src/Middleware/SpaServices/src/yarn.lock +++ b/src/Middleware/SpaServices/src/yarn.lock @@ -3,9 +3,9 @@ "@types/node@^10.9.2": - version "10.14.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.13.tgz#ac786d623860adf39a3f51d629480aacd6a6eec7" - integrity sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ== + version "10.17.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.6.tgz#1aaabd6f6470a6ac3824ab1e94d731ca1326d93d" + integrity sha512-0a2X6cgN3RdPBL2MIlR6Lt0KlM7fOFsutuXcdglcOq6WvLnYXgPQSh0Mx6tO1KCAE8MxbHSOSTWDoUxRq+l3DA== "@webassemblyjs/ast@1.8.5": version "1.8.5" @@ -168,22 +168,22 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" - integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== +acorn@^6.2.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" + integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0: +ajv@^6.1.0, ajv@^6.10.2: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== @@ -294,9 +294,9 @@ balanced-match@^1.0.0: integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== base@^0.11.1: version "0.11.2" @@ -322,9 +322,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== bluebird@^3.5.5: - version "3.5.5" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" - integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" @@ -430,9 +430,9 @@ buffer-xor@^1.0.3: integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^4.3.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -443,16 +443,17 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -cacache@^11.3.2: - version "11.3.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" - integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== +cacache@^12.0.2: + version "12.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" + integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== dependencies: bluebird "^3.5.5" chownr "^1.1.1" figgy-pudding "^3.5.1" glob "^7.1.4" graceful-fs "^4.1.15" + infer-owner "^1.0.3" lru-cache "^5.1.1" mississippi "^3.0.0" mkdirp "^0.5.1" @@ -493,9 +494,9 @@ chalk@2.4.2, chalk@^2.3.0: supports-color "^5.3.0" chokidar@^2.0.2: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" @@ -512,11 +513,11 @@ chokidar@^2.0.2: fsevents "^1.2.7" chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== -chrome-trace-event@^1.0.0: +chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== @@ -576,9 +577,9 @@ color-name@1.1.3: integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= commander@^2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commondir@^1.0.1: version "1.0.1" @@ -606,11 +607,9 @@ concat-stream@^1.5.0: typedarray "^0.0.6" console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= - dependencies: - date-now "^0.1.4" + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" @@ -703,15 +702,10 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -cyclist@~0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" - integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= - -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -770,9 +764,9 @@ delegates@^1.0.0: integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= des.js@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" - integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -812,9 +806,9 @@ duplexify@^3.4.2, duplexify@^3.6.0: stream-shift "^1.0.0" elliptic@^6.0.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca" - integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg== + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -835,13 +829,13 @@ emojis-list@^2.0.0: integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enhanced-resolve@4.1.0, enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: +enhanced-resolve@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== @@ -850,6 +844,15 @@ enhanced-resolve@4.1.0, enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: memory-fs "^0.4.0" tapable "^1.0.0" +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -862,7 +865,7 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -eslint-scope@^4.0.0: +eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== @@ -878,9 +881,9 @@ esrecurse@^4.1.0: estraverse "^4.1.0" estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== events@^3.0.0: version "3.0.0" @@ -982,7 +985,7 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" -find-cache-dir@^2.0.0: +find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== @@ -1037,11 +1040,11 @@ from2@^2.1.0: readable-stream "^2.0.0" fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: - minipass "^2.2.1" + minipass "^2.6.0" fs-write-stream-atomic@^1.0.8: version "1.0.10" @@ -1106,9 +1109,9 @@ glob-parent@^3.1.0: path-dirname "^1.0.0" glob@^7.1.3, glob@^7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1154,9 +1157,9 @@ global-prefix@^3.0.0: which "^1.3.1" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== has-flag@^3.0.0: version "3.0.0" @@ -1254,9 +1257,9 @@ iferr@^0.1.5: integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== dependencies: minimatch "^3.0.4" @@ -1273,6 +1276,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1511,12 +1519,12 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" -loader-runner@^2.3.0: +loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: +loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== @@ -1590,7 +1598,7 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" -memory-fs@^0.4.0, memory-fs@~0.4.1: +memory-fs@^0.4.0, memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -1598,7 +1606,15 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -1657,20 +1673,20 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== dependencies: - minipass "^2.2.1" + minipass "^2.9.0" mississippi@^3.0.0: version "3.0.0" @@ -1696,7 +1712,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -1756,7 +1772,7 @@ needle@^2.2.1: iconv-lite "^0.4.4" sax "^1.2.4" -neo-async@^2.5.0: +neo-async@^2.5.0, neo-async@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== @@ -1766,7 +1782,7 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-libs-browser@^2.0.0: +node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== @@ -1837,9 +1853,9 @@ npm-bundled@^1.0.1: integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== npm-packlist@^1.1.6: - version "1.4.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" - integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== + version "1.4.6" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" + integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== dependencies: ignore-walk "^3.0.1" npm-bundled "^1.0.1" @@ -1949,9 +1965,9 @@ p-is-promise@^2.0.0: integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== p-limit@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: p-try "^2.0.0" @@ -1973,18 +1989,18 @@ pako@~1.0.5: integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== parallel-transform@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" - integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== dependencies: - cyclist "~0.2.2" + cyclist "^1.0.1" inherits "^2.0.3" readable-stream "^2.1.5" parse-asn1@^5.0.0: - version "5.1.4" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" - integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -2249,9 +2265,9 @@ ret@~0.1.10: integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" @@ -2270,7 +2286,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -2307,14 +2323,14 @@ schema-utils@^1.0.0: ajv-keywords "^3.1.0" semver@^5.0.1, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -serialize-javascript@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" - integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== +serialize-javascript@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" + integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -2408,9 +2424,9 @@ source-map-resolve@^0.5.0: urix "^0.1.0" source-map-support@~0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + version "0.5.16" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" + integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -2511,11 +2527,11 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string_decoder@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: - safe-buffer "~5.1.0" + safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" @@ -2569,44 +2585,43 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -tapable@^1.0.0, tapable@^1.1.0: +tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.5" + minipass "^2.8.6" minizlib "^1.2.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" yallist "^3.0.3" -terser-webpack-plugin@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz#69aa22426299f4b5b3775cbed8cb2c5d419aa1d4" - integrity sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg== +terser-webpack-plugin@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz#e23c0d554587d1f473bd0cf68627720e733890a4" + integrity sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew== dependencies: - cacache "^11.3.2" - find-cache-dir "^2.0.0" + cacache "^12.0.2" + find-cache-dir "^2.1.0" is-wsl "^1.1.0" - loader-utils "^1.2.3" schema-utils "^1.0.0" - serialize-javascript "^1.7.0" + serialize-javascript "^2.1.1" source-map "^0.6.1" - terser "^4.0.0" - webpack-sources "^1.3.0" + terser "^4.1.2" + webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391" - integrity sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw== +terser@^4.1.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.2.tgz#448fffad0245f4c8a277ce89788b458bfd7706e8" + integrity sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -2621,9 +2636,9 @@ through2@^2.0.0: xtend "~4.0.1" timers-browserify@^2.0.4: - version "2.0.10" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" - integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== dependencies: setimmediate "^1.0.4" @@ -2684,9 +2699,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^3.0.1: - version "3.5.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" - integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== + version "3.7.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.3.tgz#b36840668a16458a7025b9eabfad11b66ab85c69" + integrity sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw== union-value@^1.0.0: version "1.0.1" @@ -2721,9 +2736,9 @@ unset-value@^1.0.0: isobject "^3.0.0" upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" - integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: version "4.2.2" @@ -2775,11 +2790,11 @@ v8-compile-cache@2.0.3: integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== vm-browserify@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" - integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -watchpack@^1.5.0: +watchpack@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== @@ -2789,9 +2804,9 @@ watchpack@^1.5.0: neo-async "^2.5.0" webpack-cli@^3.1.0: - version "3.3.6" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.6.tgz#2c8c399a2642133f8d736a359007a052e060032c" - integrity sha512-0vEa83M7kJtxK/jUhlpZ27WHIOndz5mghWL2O53kiDoA9DIxSKnfqB92LoqEn77cT4f3H2cZm1BMEat/6AZz3A== + version "3.3.10" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.10.tgz#17b279267e9b4fb549023fae170da8e6e766da13" + integrity sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg== dependencies: chalk "2.4.2" cross-spawn "6.0.5" @@ -2805,42 +2820,42 @@ webpack-cli@^3.1.0: v8-compile-cache "2.0.3" yargs "13.2.4" -webpack-sources@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" - integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== +webpack-sources@^1.4.0, webpack-sources@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" source-map "~0.6.1" webpack@^4.17.1: - version "4.36.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.36.1.tgz#f546fda7a403a76faeaaa7196c50d12370ed18a9" - integrity sha512-Ej01/N9W8DVyhEpeQnbUdGvOECw0L46FxS12cCOs8gSK7bhUlrbHRnWkjiXckGlHjUrmL89kDpTRIkUk6Y+fKg== + version "4.41.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e" + integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A== dependencies: "@webassemblyjs/ast" "1.8.5" "@webassemblyjs/helper-module-context" "1.8.5" "@webassemblyjs/wasm-edit" "1.8.5" "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.2.0" - ajv "^6.1.0" - ajv-keywords "^3.1.0" - chrome-trace-event "^1.0.0" + acorn "^6.2.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" enhanced-resolve "^4.1.0" - eslint-scope "^4.0.0" + eslint-scope "^4.0.3" json-parse-better-errors "^1.0.2" - loader-runner "^2.3.0" - loader-utils "^1.1.0" - memory-fs "~0.4.1" - micromatch "^3.1.8" - mkdirp "~0.5.0" - neo-async "^2.5.0" - node-libs-browser "^2.0.0" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.1" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" schema-utils "^1.0.0" - tapable "^1.1.0" - terser-webpack-plugin "^1.1.0" - watchpack "^1.5.0" - webpack-sources "^1.3.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.1" + watchpack "^1.6.0" + webpack-sources "^1.4.1" which-module@^2.0.0: version "2.0.0" @@ -2893,9 +2908,9 @@ y18n@^4.0.0: integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yargs-parser@^13.1.0: version "13.1.1" diff --git a/src/Middleware/StaticFiles/ref/Microsoft.AspNetCore.StaticFiles.netcoreapp.cs b/src/Middleware/StaticFiles/ref/Microsoft.AspNetCore.StaticFiles.netcoreapp.cs index 424801bb14..616982bcad 100644 --- a/src/Middleware/StaticFiles/ref/Microsoft.AspNetCore.StaticFiles.netcoreapp.cs +++ b/src/Middleware/StaticFiles/ref/Microsoft.AspNetCore.StaticFiles.netcoreapp.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Builder { public DefaultFilesOptions() : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } public DefaultFilesOptions(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } - public System.Collections.Generic.IList DefaultFileNames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList DefaultFileNames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class DirectoryBrowserExtensions { @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Builder { public DirectoryBrowserOptions() : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } public DirectoryBrowserOptions(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } - public Microsoft.AspNetCore.StaticFiles.IDirectoryFormatter Formatter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.StaticFiles.IDirectoryFormatter Formatter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class FileServerExtensions { @@ -37,11 +37,11 @@ namespace Microsoft.AspNetCore.Builder public partial class FileServerOptions : Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptionsBase { public FileServerOptions() : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } - public Microsoft.AspNetCore.Builder.DefaultFilesOptions DefaultFilesOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Builder.DirectoryBrowserOptions DirectoryBrowserOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnableDefaultFiles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool EnableDirectoryBrowsing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Builder.StaticFileOptions StaticFileOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Builder.DefaultFilesOptions DefaultFilesOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Builder.DirectoryBrowserOptions DirectoryBrowserOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnableDefaultFiles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool EnableDirectoryBrowsing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Builder.StaticFileOptions StaticFileOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class StaticFileExtensions { @@ -53,11 +53,11 @@ namespace Microsoft.AspNetCore.Builder { public StaticFileOptions() : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } public StaticFileOptions(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) : base (default(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions)) { } - public Microsoft.AspNetCore.StaticFiles.IContentTypeProvider ContentTypeProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DefaultContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Features.HttpsCompressionMode HttpsCompression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action OnPrepareResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ServeUnknownFileTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.StaticFiles.IContentTypeProvider ContentTypeProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DefaultContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Features.HttpsCompressionMode HttpsCompression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action OnPrepareResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ServeUnknownFileTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class StaticFilesEndpointRouteBuilderExtensions { @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.StaticFiles { public FileExtensionContentTypeProvider() { } public FileExtensionContentTypeProvider(System.Collections.Generic.IDictionary mapping) { } - public System.Collections.Generic.IDictionary Mappings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Mappings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool TryGetContentType(string subpath, out string contentType) { throw null; } } public partial class HtmlDirectoryFormatter : Microsoft.AspNetCore.StaticFiles.IDirectoryFormatter @@ -110,8 +110,8 @@ namespace Microsoft.AspNetCore.StaticFiles [System.ObsoleteAttribute("Use the constructor that passes in the HttpContext and IFileInfo parameters: StaticFileResponseContext(HttpContext context, IFileInfo file)", false)] public StaticFileResponseContext() { } public StaticFileResponseContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.Extensions.FileProviders.IFileInfo file) { } - public Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.FileProviders.IFileInfo File { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.FileProviders.IFileInfo File { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.StaticFiles.Infrastructure @@ -119,15 +119,17 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure public partial class SharedOptions { public SharedOptions() { } - public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RedirectToAppendTrailingSlash { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.PathString RequestPath { get { throw null; } set { } } } public abstract partial class SharedOptionsBase { protected SharedOptionsBase(Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions sharedOptions) { } public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { get { throw null; } set { } } + public bool RedirectToAppendTrailingSlash { get { throw null; } set { } } public Microsoft.AspNetCore.Http.PathString RequestPath { get { throw null; } set { } } - protected Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions SharedOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.StaticFiles.Infrastructure.SharedOptions SharedOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Middleware/StaticFiles/src/Constants.cs b/src/Middleware/StaticFiles/src/Constants.cs index b98937a747..275a90fd34 100644 --- a/src/Middleware/StaticFiles/src/Constants.cs +++ b/src/Middleware/StaticFiles/src/Constants.cs @@ -10,11 +10,5 @@ namespace Microsoft.AspNetCore.StaticFiles internal const string ServerCapabilitiesKey = "server.Capabilities"; internal const string SendFileVersionKey = "sendfile.Version"; internal const string SendFileVersion = "1.0"; - - internal const int Status200Ok = 200; - internal const int Status206PartialContent = 206; - internal const int Status304NotModified = 304; - internal const int Status412PreconditionFailed = 412; - internal const int Status416RangeNotSatisfiable = 416; } } diff --git a/src/Middleware/StaticFiles/src/DefaultFilesMiddleware.cs b/src/Middleware/StaticFiles/src/DefaultFilesMiddleware.cs index 3aabe2fe65..9232197fa2 100644 --- a/src/Middleware/StaticFiles/src/DefaultFilesMiddleware.cs +++ b/src/Middleware/StaticFiles/src/DefaultFilesMiddleware.cs @@ -63,8 +63,8 @@ namespace Microsoft.AspNetCore.StaticFiles /// public Task Invoke(HttpContext context) { - if (context.GetEndpoint() == null && - Helpers.IsGetOrHeadMethod(context.Request.Method) + if (context.GetEndpoint() == null + && Helpers.IsGetOrHeadMethod(context.Request.Method) && Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out var subpath)) { var dirContents = _fileProvider.GetDirectoryContents(subpath.Value); @@ -80,17 +80,13 @@ namespace Microsoft.AspNetCore.StaticFiles { // If the path matches a directory but does not end in a slash, redirect to add the slash. // This prevents relative links from breaking. - if (!Helpers.PathEndsInSlash(context.Request.Path)) + if (_options.RedirectToAppendTrailingSlash && !Helpers.PathEndsInSlash(context.Request.Path)) { - context.Response.StatusCode = StatusCodes.Status301MovedPermanently; - var request = context.Request; - var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString); - context.Response.Headers[HeaderNames.Location] = redirect; + Helpers.RedirectToPathWithSlash(context); return Task.CompletedTask; } - // Match found, re-write the url. A later middleware will actually serve the file. - context.Request.Path = new PathString(context.Request.Path.Value + defaultFile); + context.Request.Path = new PathString(Helpers.GetPathValueWithSlash(context.Request.Path) + defaultFile); break; } } diff --git a/src/Middleware/StaticFiles/src/DirectoryBrowserMiddleware.cs b/src/Middleware/StaticFiles/src/DirectoryBrowserMiddleware.cs index 2d0a07b509..c4cc0049ad 100644 --- a/src/Middleware/StaticFiles/src/DirectoryBrowserMiddleware.cs +++ b/src/Middleware/StaticFiles/src/DirectoryBrowserMiddleware.cs @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.StaticFiles _next = next; _options = options.Value; _fileProvider = _options.FileProvider ?? Helpers.ResolveFileProvider(hostingEnv); - _formatter = options.Value.Formatter ?? new HtmlDirectoryFormatter(encoder); + _formatter = _options.Formatter ?? new HtmlDirectoryFormatter(encoder); _matchUrl = _options.RequestPath; } @@ -80,19 +80,16 @@ namespace Microsoft.AspNetCore.StaticFiles public Task Invoke(HttpContext context) { // Check if the URL matches any expected paths, skip if an endpoint was selected - if (context.GetEndpoint() == null && - Helpers.IsGetOrHeadMethod(context.Request.Method) + if (context.GetEndpoint() == null + && Helpers.IsGetOrHeadMethod(context.Request.Method) && Helpers.TryMatchPath(context, _matchUrl, forDirectory: true, subpath: out var subpath) && TryGetDirectoryInfo(subpath, out var contents)) { // If the path matches a directory but does not end in a slash, redirect to add the slash. // This prevents relative links from breaking. - if (!Helpers.PathEndsInSlash(context.Request.Path)) + if (_options.RedirectToAppendTrailingSlash && !Helpers.PathEndsInSlash(context.Request.Path)) { - context.Response.StatusCode = StatusCodes.Status301MovedPermanently; - var request = context.Request; - var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString); - context.Response.Headers[HeaderNames.Location] = redirect; + Helpers.RedirectToPathWithSlash(context); return Task.CompletedTask; } diff --git a/src/Middleware/StaticFiles/src/FileExtensionContentTypeProvider.cs b/src/Middleware/StaticFiles/src/FileExtensionContentTypeProvider.cs index a2b603f37c..69b92c4c47 100644 --- a/src/Middleware/StaticFiles/src/FileExtensionContentTypeProvider.cs +++ b/src/Middleware/StaticFiles/src/FileExtensionContentTypeProvider.cs @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.StaticFiles { ".crt", "application/x-x509-ca-cert" }, { ".csh", "application/x-csh" }, { ".css", "text/css" }, - { ".csv", "application/octet-stream" }, + { ".csv", "text/csv" }, // https://tools.ietf.org/html/rfc7111#section-5.1 { ".cur", "application/octet-stream" }, { ".dcr", "application/x-director" }, { ".deploy", "application/octet-stream" }, diff --git a/src/Middleware/StaticFiles/src/Helpers.cs b/src/Middleware/StaticFiles/src/Helpers.cs index a7a49e9070..d9b29c082f 100644 --- a/src/Middleware/StaticFiles/src/Helpers.cs +++ b/src/Middleware/StaticFiles/src/Helpers.cs @@ -2,9 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.FileProviders; +using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.StaticFiles { @@ -12,7 +15,8 @@ namespace Microsoft.AspNetCore.StaticFiles { internal static IFileProvider ResolveFileProvider(IWebHostEnvironment hostingEnv) { - if (hostingEnv.WebRootFileProvider == null) { + if (hostingEnv.WebRootFileProvider == null) + { throw new InvalidOperationException("Missing FileProvider."); } return hostingEnv.WebRootFileProvider; @@ -28,6 +32,23 @@ namespace Microsoft.AspNetCore.StaticFiles return path.Value.EndsWith("/", StringComparison.Ordinal); } + internal static string GetPathValueWithSlash(PathString path) + { + if (!PathEndsInSlash(path)) + { + return path.Value + "/"; + } + return path.Value; + } + + internal static void RedirectToPathWithSlash(HttpContext context) + { + context.Response.StatusCode = StatusCodes.Status301MovedPermanently; + var request = context.Request; + var redirect = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path + "/", request.QueryString); + context.Response.Headers[HeaderNames.Location] = redirect; + } + internal static bool TryMatchPath(HttpContext context, PathString matchUrl, bool forDirectory, out PathString subpath) { var path = context.Request.Path; diff --git a/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs b/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs index e27624ec1c..a4d0f4a3c5 100644 --- a/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs +++ b/src/Middleware/StaticFiles/src/HtmlDirectoryFormatter.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.StaticFiles { private const string TextHtmlUtf8 = "text/html; charset=utf-8"; - private HtmlEncoder _htmlEncoder; + private readonly HtmlEncoder _htmlEncoder; /// /// Constructs the . diff --git a/src/Middleware/StaticFiles/src/Infrastructure/SharedOptions.cs b/src/Middleware/StaticFiles/src/Infrastructure/SharedOptions.cs index 1c1cc80ad5..d6f08129a1 100644 --- a/src/Middleware/StaticFiles/src/Infrastructure/SharedOptions.cs +++ b/src/Middleware/StaticFiles/src/Infrastructure/SharedOptions.cs @@ -42,5 +42,10 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure /// The file system used to locate resources /// public IFileProvider FileProvider { get; set; } + + /// + /// Indicates whether to redirect to add a trailing slash at the end of path. Relative resource links may require this. + /// + public bool RedirectToAppendTrailingSlash { get; set; } = true; } } diff --git a/src/Middleware/StaticFiles/src/Infrastructure/SharedOptionsBase.cs b/src/Middleware/StaticFiles/src/Infrastructure/SharedOptionsBase.cs index 16900ec6fb..9e41b96cdc 100644 --- a/src/Middleware/StaticFiles/src/Infrastructure/SharedOptionsBase.cs +++ b/src/Middleware/StaticFiles/src/Infrastructure/SharedOptionsBase.cs @@ -48,5 +48,14 @@ namespace Microsoft.AspNetCore.StaticFiles.Infrastructure get { return SharedOptions.FileProvider; } set { SharedOptions.FileProvider = value; } } + + /// + /// Indicates whether to redirect to add a trailing slash at the end of path. Relative resource links may require this. + /// + public bool RedirectToAppendTrailingSlash + { + get { return SharedOptions.RedirectToAppendTrailingSlash; } + set { SharedOptions.RedirectToAppendTrailingSlash = value; } + } } } diff --git a/src/Middleware/StaticFiles/src/StaticFileContext.cs b/src/Middleware/StaticFiles/src/StaticFileContext.cs index 3de3576e76..1d39b42c2e 100644 --- a/src/Middleware/StaticFiles/src/StaticFileContext.cs +++ b/src/Middleware/StaticFiles/src/StaticFileContext.cs @@ -87,9 +87,9 @@ namespace Microsoft.AspNetCore.StaticFiles } } - private RequestHeaders RequestHeaders => (_requestHeaders ??= _request.GetTypedHeaders()); + private RequestHeaders RequestHeaders => _requestHeaders ??= _request.GetTypedHeaders(); - private ResponseHeaders ResponseHeaders => (_responseHeaders ??= _response.GetTypedHeaders()); + private ResponseHeaders ResponseHeaders => _responseHeaders ??= _response.GetTypedHeaders(); public bool IsHeadMethod => _requestType.HasFlag(RequestType.IsHead); @@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.StaticFiles // 14.24 If-Match var ifMatch = requestHeaders.IfMatch; - if (ifMatch != null && ifMatch.Any()) + if (ifMatch?.Count > 0) { _ifMatchState = PreconditionState.PreconditionFailed; foreach (var etag in ifMatch) @@ -164,7 +164,7 @@ namespace Microsoft.AspNetCore.StaticFiles // 14.26 If-None-Match var ifNoneMatch = requestHeaders.IfNoneMatch; - if (ifNoneMatch != null && ifNoneMatch.Any()) + if (ifNoneMatch?.Count > 0) { _ifNoneMatchState = PreconditionState.ShouldProcess; foreach (var etag in ifNoneMatch) @@ -260,7 +260,7 @@ namespace Microsoft.AspNetCore.StaticFiles responseHeaders.ETag = _etag; responseHeaders.Headers[HeaderNames.AcceptRanges] = "bytes"; } - if (statusCode == Constants.Status200Ok) + if (statusCode == StatusCodes.Status200OK) { // this header is only returned here for 200 // it already set to the returned range for 206 @@ -304,7 +304,7 @@ namespace Microsoft.AspNetCore.StaticFiles case PreconditionState.ShouldProcess: if (IsHeadMethod) { - await SendStatusAsync(Constants.Status200Ok); + await SendStatusAsync(StatusCodes.Status200OK); return; } @@ -328,11 +328,11 @@ namespace Microsoft.AspNetCore.StaticFiles return; case PreconditionState.NotModified: _logger.FileNotModified(SubPath); - await SendStatusAsync(Constants.Status304NotModified); + await SendStatusAsync(StatusCodes.Status304NotModified); return; case PreconditionState.PreconditionFailed: _logger.PreconditionFailed(SubPath); - await SendStatusAsync(Constants.Status412PreconditionFailed); + await SendStatusAsync(StatusCodes.Status412PreconditionFailed); return; default: var exception = new NotImplementedException(GetPreconditionState().ToString()); @@ -344,7 +344,7 @@ namespace Microsoft.AspNetCore.StaticFiles public async Task SendAsync() { SetCompressionMode(); - ApplyResponseHeaders(Constants.Status200Ok); + ApplyResponseHeaders(StatusCodes.Status200OK); string physicalPath = _fileInfo.PhysicalPath; var sendFile = _context.Features.Get(); if (sendFile != null && !string.IsNullOrEmpty(physicalPath)) @@ -380,7 +380,7 @@ namespace Microsoft.AspNetCore.StaticFiles // SHOULD include a Content-Range field with a byte-range-resp-spec of "*". The instance-length specifies // the current length of the selected resource. e.g. */length ResponseHeaders.ContentRange = new ContentRangeHeaderValue(_length); - ApplyResponseHeaders(Constants.Status416RangeNotSatisfiable); + ApplyResponseHeaders(StatusCodes.Status416RangeNotSatisfiable); _logger.RangeNotSatisfiable(SubPath); return; @@ -389,7 +389,7 @@ namespace Microsoft.AspNetCore.StaticFiles ResponseHeaders.ContentRange = ComputeContentRange(_range, out var start, out var length); _response.ContentLength = length; SetCompressionMode(); - ApplyResponseHeaders(Constants.Status206PartialContent); + ApplyResponseHeaders(StatusCodes.Status206PartialContent); string physicalPath = _fileInfo.PhysicalPath; var sendFile = _context.Features.Get(); diff --git a/src/Middleware/StaticFiles/src/StaticFileMiddleware.cs b/src/Middleware/StaticFiles/src/StaticFileMiddleware.cs index a1d885b965..9e1c8c4331 100644 --- a/src/Middleware/StaticFiles/src/StaticFileMiddleware.cs +++ b/src/Middleware/StaticFiles/src/StaticFileMiddleware.cs @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.StaticFiles _next = next; _options = options.Value; - _contentTypeProvider = options.Value.ContentTypeProvider ?? new FileExtensionContentTypeProvider(); + _contentTypeProvider = _options.ContentTypeProvider ?? new FileExtensionContentTypeProvider(); _fileProvider = _options.FileProvider ?? Helpers.ResolveFileProvider(hostingEnv); _matchUrl = _options.RequestPath; _logger = loggerFactory.CreateLogger(); @@ -98,18 +98,7 @@ namespace Microsoft.AspNetCore.StaticFiles private static bool ValidateMethod(HttpContext context) { - var method = context.Request.Method; - var isValid = false; - if (HttpMethods.IsGet(method)) - { - isValid = true; - } - else if (HttpMethods.IsHead(method)) - { - isValid = true; - } - - return isValid; + return Helpers.IsGetOrHeadMethod(context.Request.Method); } internal static bool ValidatePath(HttpContext context, PathString matchUrl, out PathString subPath) => Helpers.TryMatchPath(context, matchUrl, forDirectory: false, out subPath); diff --git a/src/Middleware/StaticFiles/test/FunctionalTests/FallbackStaticFileTest.cs b/src/Middleware/StaticFiles/test/FunctionalTests/FallbackStaticFileTest.cs index 2d12ee7a30..58b80d2952 100644 --- a/src/Middleware/StaticFiles/test/FunctionalTests/FallbackStaticFileTest.cs +++ b/src/Middleware/StaticFiles/test/FunctionalTests/FallbackStaticFileTest.cs @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.StaticFiles using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel))) { var environment = server.Services.GetRequiredService(); - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var response = await client.GetAsync("hello"); var responseText = await response.Content.ReadAsStringAsync(); @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.StaticFiles using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel))) { var environment = server.Services.GetRequiredService(); - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var response = await client.GetAsync("hello"); var responseText = await response.Content.ReadAsStringAsync(); diff --git a/src/Middleware/StaticFiles/test/FunctionalTests/Helpers.cs b/src/Middleware/StaticFiles/test/FunctionalTests/Helpers.cs new file mode 100644 index 0000000000..12e634cda1 --- /dev/null +++ b/src/Middleware/StaticFiles/test/FunctionalTests/Helpers.cs @@ -0,0 +1,17 @@ +// 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.Linq; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; + +namespace Microsoft.AspNetCore.StaticFiles +{ + public static class Helpers + { + public static string GetAddress(IWebHost server) + { + return server.ServerFeatures.Get().Addresses.First(); + } + } +} diff --git a/src/Middleware/StaticFiles/test/FunctionalTests/StaticFileMiddlewareTests.cs b/src/Middleware/StaticFiles/test/FunctionalTests/StaticFileMiddlewareTests.cs index f90c79ca12..b4ca20cf0a 100644 --- a/src/Middleware/StaticFiles/test/FunctionalTests/StaticFileMiddlewareTests.cs +++ b/src/Middleware/StaticFiles/test/FunctionalTests/StaticFileMiddlewareTests.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.StaticFiles using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel))) { - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var response = await client.GetAsync("TestDocument.txt"); @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.StaticFiles using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel))) { - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var response = await client.GetAsync("TestDocument.txt"); @@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.StaticFiles using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel))) { - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var last = File.GetLastWriteTimeUtc(Path.Combine(AppContext.BaseDirectory, "TestDocument.txt")); var response = await client.GetAsync("TestDocument.txt"); @@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.StaticFiles { var hostingEnvironment = server.Services.GetService(); - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl)); var response = await client.GetAsync(requestUrl); @@ -181,7 +181,7 @@ namespace Microsoft.AspNetCore.StaticFiles { var hostingEnvironment = server.Services.GetService(); - using (var client = new HttpClient { BaseAddress = new Uri(server.GetAddress()) }) + using (var client = new HttpClient { BaseAddress = new Uri(Helpers.GetAddress(server)) }) { var fileInfo = hostingEnvironment.WebRootFileProvider.GetFileInfo(Path.GetFileName(requestUrl)); var request = new HttpRequestMessage(HttpMethod.Head, requestUrl); @@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.StaticFiles using (var server = builder.Start(TestUrlHelper.GetTestUrl(serverType))) { // We don't use HttpClient here because it's disconnect behavior varies across platforms. - var socket = SendSocketRequestAsync(server.GetAddress(), "/TestDocument1MB.txt"); + var socket = SendSocketRequestAsync(Helpers.GetAddress(server), "/TestDocument1MB.txt"); await requestReceived.Task.TimeoutAfter(interval); socket.LingerState = new LingerOption(true, 0); diff --git a/src/Middleware/StaticFiles/test/UnitTests/DefaultFilesMiddlewareTests.cs b/src/Middleware/StaticFiles/test/UnitTests/DefaultFilesMiddlewareTests.cs index ab456fd218..08e86714a4 100644 --- a/src/Middleware/StaticFiles/test/UnitTests/DefaultFilesMiddlewareTests.cs +++ b/src/Middleware/StaticFiles/test/UnitTests/DefaultFilesMiddlewareTests.cs @@ -38,9 +38,14 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("/subdir", @".", "/subdir/missing.dir")] [InlineData("/subdir", @".", "/subdir/missing.dir/")] [InlineData("", @"./", "/missing.dir")] - public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".", "/missing.dir", false)] + [InlineData("", @".", "/missing.dir/", false)] + [InlineData("/subdir", @".", "/subdir/missing.dir", false)] + [InlineData("/subdir", @".", "/subdir/missing.dir/", false)] + [InlineData("", @"./", "/missing.dir", false)] + public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl); + await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] @@ -48,12 +53,14 @@ namespace Microsoft.AspNetCore.StaticFiles [OSSkipCondition(OperatingSystems.MacOSX)] [InlineData("", @".\", "/missing.dir")] [InlineData("", @".\", "/Missing.dir")] - public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".\", "/missing.dir", false)] + [InlineData("", @".\", "/Missing.dir", false)] + public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl); + await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl) + private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { @@ -62,7 +69,8 @@ namespace Microsoft.AspNetCore.StaticFiles app.UseDefaultFiles(new DefaultFilesOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash }); app.Run(context => context.Response.WriteAsync(context.Request.Path.Value)); }); @@ -102,7 +110,7 @@ namespace Microsoft.AspNetCore.StaticFiles FileProvider = fileProvider }); - app.UseEndpoints(endpoints => {}); + app.UseEndpoints(endpoints => { }); }, services => { services.AddDirectoryBrowser(); services.AddRouting(); }); @@ -118,9 +126,19 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("", @"./SubFolder", "/")] [InlineData("", @"./SubFolder", "/你好/")] [InlineData("", @"./SubFolder", "/你好/世界/")] - public async Task FoundDirectoryWithDefaultFile_PathModified_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".", "/SubFolder/", false)] + [InlineData("", @"./", "/SubFolder/", false)] + [InlineData("", @"./SubFolder", "/", false)] + [InlineData("", @"./SubFolder", "/你好/", false)] + [InlineData("", @"./SubFolder", "/你好/世界/", false)] + [InlineData("", @".", "/SubFolder", false)] + [InlineData("", @"./", "/SubFolder", false)] + [InlineData("", @"./SubFolder", "", false)] + [InlineData("", @"./SubFolder", "/你好", false)] + [InlineData("", @"./SubFolder", "/你好/世界", false)] + public async Task FoundDirectoryWithDefaultFile_PathModified_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl); + await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] @@ -130,12 +148,20 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("", @".\subFolder", "/")] [InlineData("", @".\SubFolder", "/你好/")] [InlineData("", @".\SubFolder", "/你好/世界/")] - public async Task FoundDirectoryWithDefaultFile_PathModified_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".\", "/SubFolder/", false)] + [InlineData("", @".\subFolder", "/", false)] + [InlineData("", @".\SubFolder", "/你好/", false)] + [InlineData("", @".\SubFolder", "/你好/世界/", false)] + [InlineData("", @".\", "/SubFolder", false)] + [InlineData("", @".\subFolder", "", false)] + [InlineData("", @".\SubFolder", "/你好", false)] + [InlineData("", @".\SubFolder", "/你好/世界", false)] + public async Task FoundDirectoryWithDefaultFile_PathModified_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl); + await FoundDirectoryWithDefaultFile_PathModified(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task FoundDirectoryWithDefaultFile_PathModified(string baseUrl, string baseDir, string requestUrl) + private async Task FoundDirectoryWithDefaultFile_PathModified(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { @@ -144,14 +170,17 @@ namespace Microsoft.AspNetCore.StaticFiles app.UseDefaultFiles(new DefaultFilesOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash }); app.Run(context => context.Response.WriteAsync(context.Request.Path.Value)); }); var response = await server.CreateClient().GetAsync(requestUrl); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal(requestUrl + "default.html", await response.Content.ReadAsStringAsync()); // Should be modified + var requestUrlWithSlash = requestUrl.EndsWith("/") ? requestUrl : requestUrl + "/"; + Assert.Equal(requestUrlWithSlash + "default.html", await response.Content.ReadAsStringAsync()); // Should be modified and be valid path to file } } @@ -202,9 +231,17 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("/SubFolder", @".", "/somedir/")] [InlineData("", @"./SubFolder", "/")] [InlineData("", @"./SubFolder/", "/")] - public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("/SubFolder", @"./", "/SubFolder/", false)] + [InlineData("/SubFolder", @".", "/somedir/", false)] + [InlineData("", @"./SubFolder", "/", false)] + [InlineData("", @"./SubFolder/", "/", false)] + [InlineData("/SubFolder", @"./", "/SubFolder", false)] + [InlineData("/SubFolder", @".", "/somedir", false)] + [InlineData("", @"./SubFolder", "", false)] + [InlineData("", @"./SubFolder/", "", false)] + public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl); + await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] @@ -213,24 +250,37 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("/SubFolder", @".\", "/SubFolder/")] [InlineData("", @".\SubFolder", "/")] [InlineData("", @".\SubFolder\", "/")] - public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("/SubFolder", @".\", "/SubFolder/", false)] + [InlineData("", @".\SubFolder", "/", false)] + [InlineData("", @".\SubFolder\", "/", false)] + [InlineData("/SubFolder", @".\", "/SubFolder", false)] + [InlineData("", @".\SubFolder", "", false)] + [InlineData("", @".\SubFolder\", "", false)] + public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl); + await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl) + private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { var server = StaticFilesTestServer.Create(app => app.UseDefaultFiles(new DefaultFilesOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash })); var response = await server.CreateRequest(requestUrl).GetAsync(); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); // Passed through } } + + [Fact] + public void Options_AppendTrailingSlashByDefault() + { + Assert.True(new DefaultFilesOptions().RedirectToAppendTrailingSlash); + } } } diff --git a/src/Middleware/StaticFiles/test/UnitTests/DirectoryBrowserMiddlewareTests.cs b/src/Middleware/StaticFiles/test/UnitTests/DirectoryBrowserMiddlewareTests.cs index 3e909a24ab..5a39ec3ef9 100644 --- a/src/Middleware/StaticFiles/test/UnitTests/DirectoryBrowserMiddlewareTests.cs +++ b/src/Middleware/StaticFiles/test/UnitTests/DirectoryBrowserMiddlewareTests.cs @@ -56,9 +56,14 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("/subdir", @".", "/subdir/missing.dir")] [InlineData("/subdir", @".", "/subdir/missing.dir/")] [InlineData("", @"./", "/missing.dir")] - public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".", "/missing.dir", false)] + [InlineData("", @".", "/missing.dir/", false)] + [InlineData("/subdir", @".", "/subdir/missing.dir", false)] + [InlineData("/subdir", @".", "/subdir/missing.dir/", false)] + [InlineData("", @"./", "/missing.dir", false)] + public async Task NoMatch_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl); + await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] @@ -66,12 +71,14 @@ namespace Microsoft.AspNetCore.StaticFiles [OSSkipCondition(OperatingSystems.MacOSX)] [InlineData("", @".\", "/missing.dir")] [InlineData("", @".\", "/Missing.dir")] - public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".\", "/missing.dir", false)] + [InlineData("", @".\", "/Missing.dir", false)] + public async Task NoMatch_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl); + await NoMatch_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl) + private async Task NoMatch_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { @@ -79,7 +86,8 @@ namespace Microsoft.AspNetCore.StaticFiles app => app.UseDirectoryBrowser(new DirectoryBrowserOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash }), services => services.AddDirectoryBrowser()); var response = await server.CreateRequest(requestUrl).GetAsync(); @@ -117,7 +125,7 @@ namespace Microsoft.AspNetCore.StaticFiles FileProvider = fileProvider }); - app.UseEndpoints(endpoints => {}); + app.UseEndpoints(endpoints => { }); }, services => { services.AddDirectoryBrowser(); services.AddRouting(); }); @@ -133,9 +141,19 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("/somedir", @".", "/somedir/")] [InlineData("/somedir", @"./", "/somedir/")] [InlineData("/somedir", @".", "/somedir/SubFolder/")] - public async Task FoundDirectory_Served_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".", "/", false)] + [InlineData("", @".", "/SubFolder/", false)] + [InlineData("/somedir", @".", "/somedir/", false)] + [InlineData("/somedir", @"./", "/somedir/", false)] + [InlineData("/somedir", @".", "/somedir/SubFolder/", false)] + [InlineData("", @".", "", false)] + [InlineData("", @".", "/SubFolder", false)] + [InlineData("/somedir", @".", "/somedir", false)] + [InlineData("/somedir", @"./", "/somedir", false)] + [InlineData("/somedir", @".", "/somedir/SubFolder", false)] + public async Task FoundDirectory_Served_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await FoundDirectory_Served(baseUrl, baseDir, requestUrl); + await FoundDirectory_Served(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] @@ -143,12 +161,16 @@ namespace Microsoft.AspNetCore.StaticFiles [OSSkipCondition(OperatingSystems.MacOSX)] [InlineData("/somedir", @".\", "/somedir/")] [InlineData("/somedir", @".", "/somedir/subFolder/")] - public async Task FoundDirectory_Served_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("/somedir", @".\", "/somedir/", false)] + [InlineData("/somedir", @".", "/somedir/subFolder/", false)] + [InlineData("/somedir", @".\", "/somedir", false)] + [InlineData("/somedir", @".", "/somedir/subFolder", false)] + public async Task FoundDirectory_Served_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await FoundDirectory_Served(baseUrl, baseDir, requestUrl); + await FoundDirectory_Served(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task FoundDirectory_Served(string baseUrl, string baseDir, string requestUrl) + private async Task FoundDirectory_Served(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { @@ -156,7 +178,8 @@ namespace Microsoft.AspNetCore.StaticFiles app => app.UseDirectoryBrowser(new DirectoryBrowserOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash, }), services => services.AddDirectoryBrowser()); var response = await server.CreateRequest(requestUrl).GetAsync(); @@ -215,21 +238,31 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("", @".", "/SubFolder/")] [InlineData("/somedir", @".", "/somedir/")] [InlineData("/somedir", @".", "/somedir/SubFolder/")] - public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".", "/", false)] + [InlineData("", @".", "/SubFolder/", false)] + [InlineData("/somedir", @".", "/somedir/", false)] + [InlineData("/somedir", @".", "/somedir/SubFolder/", false)] + [InlineData("", @".", "", false)] + [InlineData("", @".", "/SubFolder", false)] + [InlineData("/somedir", @".", "/somedir", false)] + [InlineData("/somedir", @".", "/somedir/SubFolder", false)] + public async Task PostDirectory_PassesThrough_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl); + await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] [OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.MacOSX)] [InlineData("/somedir", @".", "/somedir/subFolder/")] - public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("/somedir", @".", "/somedir/subFolder/", false)] + [InlineData("/somedir", @".", "/somedir/subFolder", false)] + public async Task PostDirectory_PassesThrough_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl); + await PostDirectory_PassesThrough(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl) + private async Task PostDirectory_PassesThrough(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { @@ -237,7 +270,8 @@ namespace Microsoft.AspNetCore.StaticFiles app => app.UseDirectoryBrowser(new DirectoryBrowserOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash }), services => services.AddDirectoryBrowser()); @@ -251,21 +285,31 @@ namespace Microsoft.AspNetCore.StaticFiles [InlineData("", @".", "/SubFolder/")] [InlineData("/somedir", @".", "/somedir/")] [InlineData("/somedir", @".", "/somedir/SubFolder/")] - public async Task HeadDirectory_HeadersButNotBodyServed_All(string baseUrl, string baseDir, string requestUrl) + [InlineData("", @".", "/", false)] + [InlineData("", @".", "/SubFolder/", false)] + [InlineData("/somedir", @".", "/somedir/", false)] + [InlineData("/somedir", @".", "/somedir/SubFolder/", false)] + [InlineData("", @".", "", false)] + [InlineData("", @".", "/SubFolder", false)] + [InlineData("/somedir", @".", "/somedir", false)] + [InlineData("/somedir", @".", "/somedir/SubFolder", false)] + public async Task HeadDirectory_HeadersButNotBodyServed_All(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl); + await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl, appendTrailingSlash); } [ConditionalTheory] [OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.MacOSX)] [InlineData("/somedir", @".", "/somedir/subFolder/")] - public async Task HeadDirectory_HeadersButNotBodyServed_Windows(string baseUrl, string baseDir, string requestUrl) + [InlineData("/somedir", @".", "/somedir/subFolder/", false)] + [InlineData("/somedir", @".", "/somedir/subFolder", false)] + public async Task HeadDirectory_HeadersButNotBodyServed_Windows(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { - await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl); + await HeadDirectory_HeadersButNotBodyServed(baseUrl, baseDir, requestUrl, appendTrailingSlash); } - private async Task HeadDirectory_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl) + private async Task HeadDirectory_HeadersButNotBodyServed(string baseUrl, string baseDir, string requestUrl, bool appendTrailingSlash = true) { using (var fileProvider = new PhysicalFileProvider(Path.Combine(AppContext.BaseDirectory, baseDir))) { @@ -273,7 +317,8 @@ namespace Microsoft.AspNetCore.StaticFiles app => app.UseDirectoryBrowser(new DirectoryBrowserOptions { RequestPath = new PathString(baseUrl), - FileProvider = fileProvider + FileProvider = fileProvider, + RedirectToAppendTrailingSlash = appendTrailingSlash }), services => services.AddDirectoryBrowser()); @@ -285,5 +330,11 @@ namespace Microsoft.AspNetCore.StaticFiles Assert.Empty((await response.Content.ReadAsByteArrayAsync())); } } + + [Fact] + public void Options_AppendTrailingSlashByDefault() + { + Assert.True(new DirectoryBrowserOptions().RedirectToAppendTrailingSlash); + } } } diff --git a/src/Middleware/WebSockets/WebSockets.slnf b/src/Middleware/WebSockets/WebSockets.slnf new file mode 100644 index 0000000000..1bd3b17518 --- /dev/null +++ b/src/Middleware/WebSockets/WebSockets.slnf @@ -0,0 +1,25 @@ +{ + "solution": { + "path": "..\\Middleware.sln", + "projects": [ + "..\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj", + "..\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj", + "..\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj", + "..\\Hosting\\Server.IntegrationTesting\\src\\Microsoft.AspNetCore.Server.IntegrationTesting.csproj", + "..\\Http\\Http.Abstractions\\src\\Microsoft.AspNetCore.Http.Abstractions.csproj", + "..\\Http\\Http.Extensions\\src\\Microsoft.AspNetCore.Http.Extensions.csproj", + "..\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj", + "..\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj", + "..\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj", + "..\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj", + "..\\Http\\Headers\\src\\Microsoft.Net.Http.Headers.csproj", + "..\\Http\\Http\\src\\Microsoft.AspNetCore.Http.csproj", + "WebSockets\\samples\\EchoApp\\EchoApp.csproj", + "WebSockets\\samples\\TestServer\\WebSockets.TestServer.csproj", + "WebSockets\\src\\Microsoft.AspNetCore.WebSockets.csproj", + "WebSockets\\test\\ConformanceTests\\AutobahnTestApp\\AutobahnTestApp.csproj", + "WebSockets\\test\\ConformanceTests\\Microsoft.AspNetCore.WebSockets.ConformanceTests.csproj", + "WebSockets\\test\\UnitTests\\Microsoft.AspNetCore.WebSockets.Tests.csproj" + ] + } +} \ No newline at end of file diff --git a/src/Middleware/WebSockets/ref/Microsoft.AspNetCore.WebSockets.netcoreapp.cs b/src/Middleware/WebSockets/ref/Microsoft.AspNetCore.WebSockets.netcoreapp.cs index 6b2b1988b3..eb25bc39ae 100644 --- a/src/Middleware/WebSockets/ref/Microsoft.AspNetCore.WebSockets.netcoreapp.cs +++ b/src/Middleware/WebSockets/ref/Microsoft.AspNetCore.WebSockets.netcoreapp.cs @@ -11,9 +11,9 @@ namespace Microsoft.AspNetCore.Builder public partial class WebSocketOptions { public WebSocketOptions() { } - public System.Collections.Generic.IList AllowedOrigins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ReceiveBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AllowedOrigins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ReceiveBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.WebSockets @@ -21,9 +21,9 @@ namespace Microsoft.AspNetCore.WebSockets public partial class ExtendedWebSocketAcceptContext : Microsoft.AspNetCore.Http.WebSocketAcceptContext { public ExtendedWebSocketAcceptContext() { } - public System.TimeSpan? KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? ReceiveBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan? KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? ReceiveBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class WebSocketMiddleware { diff --git a/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj b/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj index 15f4b19a4f..c92354b6f5 100644 --- a/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj +++ b/src/Middleware/WebSockets/samples/EchoApp/EchoApp.csproj @@ -1,7 +1,8 @@ - + $(DefaultNetCoreTargetFramework) + OutOfProcess diff --git a/src/Middleware/WebSockets/samples/TestServer/App.config b/src/Middleware/WebSockets/samples/TestServer/App.config deleted file mode 100644 index 731f6de6c2..0000000000 --- a/src/Middleware/WebSockets/samples/TestServer/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Middleware/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs b/src/Middleware/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs deleted file mode 100644 index 1a5999f7d8..0000000000 --- a/src/Middleware/WebSockets/samples/TestServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TestServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TestServer")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ffe69337-e3b4-4625-8244-36bd609742ba")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Middleware/WebSockets/samples/TestServer/WebSockets.TestServer.csproj b/src/Middleware/WebSockets/samples/TestServer/WebSockets.TestServer.csproj index b3e359eaef..495754aced 100644 --- a/src/Middleware/WebSockets/samples/TestServer/WebSockets.TestServer.csproj +++ b/src/Middleware/WebSockets/samples/TestServer/WebSockets.TestServer.csproj @@ -1,58 +1,8 @@ - - - + + - Debug - AnyCPU - {4E5F5FCC-172C-44D9-BEA0-39098A79CD0B} + net472 Exe - Properties - TestServer - TestServer - v4.6.1 - 512 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - + diff --git a/src/Middleware/WebSockets/src/HandshakeHelpers.cs b/src/Middleware/WebSockets/src/HandshakeHelpers.cs index 0162751f16..64e6c435da 100644 --- a/src/Middleware/WebSockets/src/HandshakeHelpers.cs +++ b/src/Middleware/WebSockets/src/HandshakeHelpers.cs @@ -23,6 +23,16 @@ namespace Microsoft.AspNetCore.WebSockets HeaderNames.SecWebSocketVersion }; + // "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + private static ReadOnlySpan EncodedWebSocketKey => new byte[] + { + (byte)'2', (byte)'5', (byte)'8', (byte)'E', (byte)'A', (byte)'F', (byte)'A', (byte)'5', (byte)'-', + (byte)'E', (byte)'9', (byte)'1', (byte)'4', (byte)'-', (byte)'4', (byte)'7', (byte)'D', (byte)'A', + (byte)'-', (byte)'9', (byte)'5', (byte)'C', (byte)'A', (byte)'-', (byte)'C', (byte)'5', (byte)'A', + (byte)'B', (byte)'0', (byte)'D', (byte)'C', (byte)'8', (byte)'5', (byte)'B', (byte)'1', (byte)'1' + }; + // Verify Method, Upgrade, Connection, version, key, etc.. public static bool CheckSupportedWebSocketRequest(string method, IEnumerable> headers) { @@ -87,34 +97,34 @@ namespace Microsoft.AspNetCore.WebSockets { return false; } - try - { - byte[] data = Convert.FromBase64String(value); - return data.Length == 16; - } - catch (Exception) - { - return false; - } + + Span temp = stackalloc byte[16]; + var success = Convert.TryFromBase64String(value, temp, out var written); + return success && written == 16; } public static string CreateResponseKey(string requestKey) { // "The value of this header field is constructed by concatenating /key/, defined above in step 4 - // in Section 4.2.2, with the string "258EAFA5- E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of + // in Section 4.2.2, with the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of // this concatenated value to obtain a 20-byte value and base64-encoding" // https://tools.ietf.org/html/rfc6455#section-4.2.2 - if (requestKey == null) - { - throw new ArgumentNullException(nameof(requestKey)); - } - using (var algorithm = SHA1.Create()) { - string merged = requestKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - byte[] mergedBytes = Encoding.UTF8.GetBytes(merged); - byte[] hashedBytes = algorithm.ComputeHash(mergedBytes); + // requestKey is already verified to be small (24 bytes) by 'IsRequestKeyValid()' and everything is 1:1 mapping to UTF8 bytes + // so this can be hardcoded to 60 bytes for the requestKey + static websocket string + Span mergedBytes = stackalloc byte[60]; + Encoding.UTF8.GetBytes(requestKey, mergedBytes); + EncodedWebSocketKey.CopyTo(mergedBytes.Slice(24)); + + Span hashedBytes = stackalloc byte[20]; + var success = algorithm.TryComputeHash(mergedBytes, hashedBytes, out var written); + if (!success || written != 20) + { + throw new InvalidOperationException("Could not compute the hash for the 'Sec-WebSocket-Accept' header."); + } + return Convert.ToBase64String(hashedBytes); } } diff --git a/src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj b/src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj index a6fe40e2b2..87fed578b9 100644 --- a/src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj +++ b/src/Middleware/WebSockets/src/Microsoft.AspNetCore.WebSockets.csproj @@ -1,4 +1,4 @@ - + ASP.NET Core web socket middleware for use on top of opaque servers. @@ -17,4 +17,8 @@ + + + + diff --git a/src/Middleware/WebSockets/src/WebSocketMiddleware.cs b/src/Middleware/WebSockets/src/WebSocketMiddleware.cs index bff8a770d2..d76100f4a4 100644 --- a/src/Middleware/WebSockets/src/WebSocketMiddleware.cs +++ b/src/Middleware/WebSockets/src/WebSocketMiddleware.cs @@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; @@ -146,7 +145,7 @@ namespace Microsoft.AspNetCore.WebSockets } } - string key = string.Join(", ", _context.Request.Headers[HeaderNames.SecWebSocketKey]); + string key = _context.Request.Headers[HeaderNames.SecWebSocketKey]; HandshakeHelpers.GenerateResponseHeaders(key, subProtocol, _context.Response.Headers); diff --git a/src/Middleware/WebSockets/src/WebSocketMiddlewareExtensions.cs b/src/Middleware/WebSockets/src/WebSocketMiddlewareExtensions.cs index 403271f09a..4b2ce7134e 100644 --- a/src/Middleware/WebSockets/src/WebSocketMiddlewareExtensions.cs +++ b/src/Middleware/WebSockets/src/WebSocketMiddlewareExtensions.cs @@ -7,8 +7,20 @@ using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Builder { + /// + /// extension methods to add and configure . + /// public static class WebSocketMiddlewareExtensions { + /// + /// Adds the to the request pipeline. + /// + /// + /// The to configure. + /// + /// + /// The . + /// public static IApplicationBuilder UseWebSockets(this IApplicationBuilder app) { if (app == null) @@ -19,6 +31,18 @@ namespace Microsoft.AspNetCore.Builder return app.UseMiddleware(); } + /// + /// Adds the to the request pipeline. + /// + /// + /// The to configure. + /// + /// + /// The to be used for the . + /// + /// + /// The . + /// public static IApplicationBuilder UseWebSockets(this IApplicationBuilder app, WebSocketOptions options) { if (app == null) @@ -33,4 +57,4 @@ namespace Microsoft.AspNetCore.Builder return app.UseMiddleware(Options.Create(options)); } } -} \ No newline at end of file +} diff --git a/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnTester.cs b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnTester.cs index f4b4a2fd8e..7e985a0599 100644 --- a/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnTester.cs +++ b/src/Middleware/WebSockets/test/ConformanceTests/Autobahn/AutobahnTester.cs @@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.WebSockets.ConformanceTest.Autobahn { Scheme = (ssl ? Uri.UriSchemeHttps : Uri.UriSchemeHttp), ApplicationType = ApplicationType.Portable, - TargetFramework = "netcoreapp3.1", + TargetFramework = "netcoreapp5.0", EnvironmentName = environment, SiteName = "HttpTestSite", // This is configured in the Http.config ServerConfigTemplateContent = (server == ServerType.IISExpress) ? File.ReadAllText(configPath) : null, diff --git a/src/Middleware/WebSockets/test/ConformanceTests/AutobahnTests.cs b/src/Middleware/WebSockets/test/ConformanceTests/AutobahnTests.cs index 708e31bf7d..7e452f17d9 100644 --- a/src/Middleware/WebSockets/test/ConformanceTests/AutobahnTests.cs +++ b/src/Middleware/WebSockets/test/ConformanceTests/AutobahnTests.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.WebSockets.ConformanceTest // Skip if wstest is not installed for now, see https://github.com/aspnet/WebSockets/issues/95 // We will enable Wstest on every build once we've gotten the necessary infrastructure sorted out :). - [ConditionalFact(Skip = "https://github.com/aspnet/AspNetCore/issues/4350")] + [ConditionalFact(Skip = "https://github.com/dotnet/aspnetcore/issues/4350")] [SkipIfWsTestNotPresent] public async Task AutobahnTestSuite() { diff --git a/src/Middleware/WebSockets/test/UnitTests/HandshakeTests.cs b/src/Middleware/WebSockets/test/UnitTests/HandshakeTests.cs new file mode 100644 index 0000000000..ec19793ddc --- /dev/null +++ b/src/Middleware/WebSockets/test/UnitTests/HandshakeTests.cs @@ -0,0 +1,41 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.WebSockets.Tests +{ + public class HandshakeTests + { + [Fact] + public void CreatesCorrectResponseKey() + { + // Example taken from https://tools.ietf.org/html/rfc6455#section-1.3 + var key = "dGhlIHNhbXBsZSBub25jZQ=="; + var expectedResponse = "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="; + + var response = HandshakeHelpers.CreateResponseKey(key); + + Assert.Equal(expectedResponse, response); + } + + [Theory] + [InlineData("VUfWn1u2Ot0AICM6f+/8Zg==")] + public void AcceptsValidRequestKeys(string key) + { + Assert.True(HandshakeHelpers.IsRequestKeyValid(key)); + } + + [Theory] + // 17 bytes when decoded + [InlineData("dGhpcyBpcyAxNyBieXRlcy4=")] + // 15 bytes when decoded + [InlineData("dGhpcyBpcyAxNWJ5dGVz")] + [InlineData("")] + [InlineData("24 length not base64 str")] + public void RejectsInvalidRequestKeys(string key) + { + Assert.False(HandshakeHelpers.IsRequestKeyValid(key)); + } + } +} diff --git a/src/Middleware/WebSockets/test/UnitTests/WebSocketMiddlewareTests.cs b/src/Middleware/WebSockets/test/UnitTests/WebSocketMiddlewareTests.cs index 89e815a75a..c4a2c64d83 100644 --- a/src/Middleware/WebSockets/test/UnitTests/WebSocketMiddlewareTests.cs +++ b/src/Middleware/WebSockets/test/UnitTests/WebSocketMiddlewareTests.cs @@ -550,7 +550,7 @@ namespace Microsoft.AspNetCore.WebSockets.Test } [Fact] - [Flaky("https://github.com/aspnet/AspNetCore/issues/8187", FlakyOn.Helix.All)] + [Flaky("https://github.com/dotnet/aspnetcore/issues/8187", FlakyOn.Helix.All)] public async Task OriginIsNotValidatedForNonWebSocketRequests() { using (var server = KestrelWebSocketHelpers.CreateServer(LoggerFactory, out var port, context => diff --git a/src/Middleware/perf/Microbenchmarks/AssemblyInfo.cs b/src/Middleware/perf/Microbenchmarks/AssemblyInfo.cs new file mode 100644 index 0000000000..32248e0d1b --- /dev/null +++ b/src/Middleware/perf/Microbenchmarks/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: BenchmarkDotNet.Attributes.AspNetCoreBenchmark] diff --git a/src/Middleware/perf/Microbenchmarks/HandshakeBenchmark.cs b/src/Middleware/perf/Microbenchmarks/HandshakeBenchmark.cs new file mode 100644 index 0000000000..ba736578b0 --- /dev/null +++ b/src/Middleware/perf/Microbenchmarks/HandshakeBenchmark.cs @@ -0,0 +1,41 @@ +// 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 BenchmarkDotNet.Attributes; + +namespace Microsoft.AspNetCore.WebSockets.Microbenchmarks +{ + public class HandshakeBenchmark + { + private string[] _requestKeys = { + "F8/qpj9RYr2/sIymdDvlmw==", + "PyQi8nyMkKnI7JKiAJ/IrA==", + "CUe0z8ItSBRtgJlPqP1+SQ==", + "w9vo1A9oM56M31qPQYKL6g==", + "+vqFGD9U04QOxKdWHrduTQ==", + "xsfuh2ZOm5O7zTzFPWJGUA==", + "TvmUzr4DgBLcDYX88kEAyw==", + "EZ5tcEOxWm7tF6adFXLSQg==", + "bkmoBhqwbbRzL8H9hvH1tQ==", + "EUwBrmmwivd5czsxz9eRzQ==", + }; + + [Benchmark(OperationsPerInvoke = 10)] + public void CreateResponseKey() + { + foreach (var key in _requestKeys) + { + HandshakeHelpers.CreateResponseKey(key); + } + } + + [Benchmark(OperationsPerInvoke = 10)] + public void IsRequestKeyValid() + { + foreach (var key in _requestKeys) + { + HandshakeHelpers.IsRequestKeyValid(key); + } + } + } +} diff --git a/src/Middleware/perf/Microbenchmarks/Microsoft.AspNetCore.WebSockets.Microbenchmarks.csproj b/src/Middleware/perf/Microbenchmarks/Microsoft.AspNetCore.WebSockets.Microbenchmarks.csproj new file mode 100644 index 0000000000..96a0535de7 --- /dev/null +++ b/src/Middleware/perf/Microbenchmarks/Microsoft.AspNetCore.WebSockets.Microbenchmarks.csproj @@ -0,0 +1,13 @@ + + + + Exe + $(DefaultNetCoreTargetFramework) + + + + + + + + diff --git a/src/MusicStore/README.md b/src/MusicStore/README.md index 011866be61..a06b3d3061 100644 --- a/src/MusicStore/README.md +++ b/src/MusicStore/README.md @@ -1,7 +1,7 @@ MusicStore (test application) ============================= -This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/aspnetcore) repo. +This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/dotnet/aspnetcore) repo. This is a test application used for ASP.NET Core internal test processes. It is not intended to be a representative sample of how to use ASP.NET Core. diff --git a/src/MusicStore/test/MusicStore.E2ETests/Common/Helpers.cs b/src/MusicStore/test/MusicStore.E2ETests/Common/Helpers.cs index eb761e21a5..0ac791dbbb 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/Common/Helpers.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/Common/Helpers.cs @@ -9,7 +9,7 @@ namespace E2ETests { public static string GetApplicationPath() { - // https://github.com/aspnet/AspNetCore/issues/8343 + // https://github.com/dotnet/aspnetcore/issues/8343 #pragma warning disable 0618 var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("MusicStore"); #pragma warning restore 0618 diff --git a/src/MusicStore/test/MusicStore.E2ETests/DotnetRunTests.cs b/src/MusicStore/test/MusicStore.E2ETests/DotnetRunTests.cs index a77a7ee26d..ed7fb66de9 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/DotnetRunTests.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/DotnetRunTests.cs @@ -17,7 +17,7 @@ namespace E2ETests { public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.Kestrel) - .WithTfms(Tfm.NetCoreApp31); + .WithTfms(Tfm.NetCoreApp50); [ConditionalTheory] [MemberData(nameof(TestVariants))] diff --git a/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj b/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj index 09854d0428..5448a235be 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj +++ b/src/MusicStore/test/MusicStore.E2ETests/MusicStore.E2ETests.csproj @@ -8,7 +8,7 @@ true true - + false false false diff --git a/src/MusicStore/test/MusicStore.E2ETests/NtlmAuthentationTest.cs b/src/MusicStore/test/MusicStore.E2ETests/NtlmAuthentationTest.cs index 27f1a89955..ee2973fe1b 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/NtlmAuthentationTest.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/NtlmAuthentationTest.cs @@ -18,7 +18,7 @@ namespace E2ETests { public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllArchitectures(); diff --git a/src/MusicStore/test/MusicStore.E2ETests/OpenIdConnectTests.cs b/src/MusicStore/test/MusicStore.E2ETests/OpenIdConnectTests.cs index 72a7433d51..5e59c33c38 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/OpenIdConnectTests.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/OpenIdConnectTests.cs @@ -15,7 +15,7 @@ namespace E2ETests { public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Kestrel) - .WithTfms(Tfm.NetCoreApp31); + .WithTfms(Tfm.NetCoreApp50); [ConditionalTheory] [MemberData(nameof(TestVariants))] diff --git a/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs b/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs index baee1468f5..d0760c261f 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/PublishAndRunTests.cs @@ -16,7 +16,7 @@ namespace E2ETests { public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllHostingModels() .WithAllArchitectures(); diff --git a/src/MusicStore/test/MusicStore.E2ETests/SmokeTests.cs b/src/MusicStore/test/MusicStore.E2ETests/SmokeTests.cs index 5fd0c206d3..26d8cd2771 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/SmokeTests.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/SmokeTests.cs @@ -17,7 +17,7 @@ namespace E2ETests { public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Kestrel, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllHostingModels(); diff --git a/src/MusicStore/test/MusicStore.E2ETests/SmokeTestsOnNanoServer.cs b/src/MusicStore/test/MusicStore.E2ETests/SmokeTestsOnNanoServer.cs index 9d6b9dea44..490d2148ce 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/SmokeTestsOnNanoServer.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/SmokeTestsOnNanoServer.cs @@ -244,7 +244,7 @@ namespace E2ETests _remoteDeploymentConfig.AccountName, _remoteDeploymentConfig.AccountPassword) { - TargetFramework = Tfm.NetCoreApp31, + TargetFramework = Tfm.NetCoreApp50, ApplicationBaseUriHint = applicationBaseUrl, ApplicationType = applicationType }; diff --git a/src/MusicStore/test/MusicStore.E2ETests/StoreSmokeTests.cs b/src/MusicStore/test/MusicStore.E2ETests/StoreSmokeTests.cs index f5f57f4c04..5995c16391 100644 --- a/src/MusicStore/test/MusicStore.E2ETests/StoreSmokeTests.cs +++ b/src/MusicStore/test/MusicStore.E2ETests/StoreSmokeTests.cs @@ -34,7 +34,7 @@ namespace E2ETests EnvironmentName = "SocialTesting", PublishApplicationBeforeDeployment = true, PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging, - TargetFramework = Tfm.NetCoreApp31, + TargetFramework = Tfm.NetCoreApp50, UserAdditionalCleanup = parameters => { DbUtils.DropDatabase(musicStoreDbName, logger); diff --git a/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs b/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs index 2632e58070..1b3315aa2e 100644 --- a/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs +++ b/src/MusicStore/test/MusicStore.Test/ShoppingCartControllerTest.cs @@ -77,7 +77,7 @@ namespace MusicStore.Controllers Assert.Equal(0, model.CartTotal); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12097")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12097")] public async Task Index_ReturnsCartItems_WhenItemsInCart() { // Arrange @@ -113,7 +113,7 @@ namespace MusicStore.Controllers Assert.Equal(5 * 10, model.CartTotal); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12097")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12097")] public async Task AddToCart_AddsItemToCart() { // Arrange @@ -155,7 +155,7 @@ namespace MusicStore.Controllers Assert.Equal("Index", redirectResult.ActionName); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12097")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12097")] public async Task RemoveFromCart_RemovesItemFromCart() { // Arrange diff --git a/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs b/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs index 003cfa201b..f60d50cb40 100644 --- a/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs +++ b/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs @@ -9,10 +9,10 @@ namespace Microsoft.AspNetCore.Mvc public ActionContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor) { } public ActionContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { } public ActionContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IActionResult { @@ -33,16 +33,16 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions public partial class ActionDescriptor { public ActionDescriptor() { } - public System.Collections.Generic.IList ActionConstraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Routing.AttributeRouteInfo AttributeRouteInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList BoundProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList EndpointMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList FilterDescriptors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList ActionConstraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Routing.AttributeRouteInfo AttributeRouteInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList BoundProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList EndpointMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList FilterDescriptors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class ActionDescriptorExtensions { @@ -52,13 +52,13 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions public partial class ActionDescriptorProviderContext { public ActionDescriptorProviderContext() { } - public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ActionInvokerProviderContext { public ActionInvokerProviderContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Abstractions.IActionInvoker Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.IActionInvoker Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IActionDescriptorProvider { @@ -79,9 +79,9 @@ namespace Microsoft.AspNetCore.Mvc.Abstractions public partial class ParameterDescriptor { public ParameterDescriptor() { } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ParameterType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ParameterType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Mvc.ActionConstraints @@ -89,31 +89,32 @@ namespace Microsoft.AspNetCore.Mvc.ActionConstraints public partial class ActionConstraintContext { public ActionConstraintContext() { } - public System.Collections.Generic.IReadOnlyList Candidates { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ActionConstraints.ActionSelectorCandidate CurrentCandidate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteContext RouteContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IReadOnlyList Candidates { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ActionConstraints.ActionSelectorCandidate CurrentCandidate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteContext RouteContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ActionConstraintItem { public ActionConstraintItem(Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata metadata) { } - public Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint Constraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint Constraint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ActionConstraintProviderContext { public ActionConstraintProviderContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor action, System.Collections.Generic.IList items) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ActionSelectorCandidate { private readonly object _dummy; + private readonly int _dummyPrimitive; public ActionSelectorCandidate(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor action, System.Collections.Generic.IReadOnlyList constraints) { throw null; } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IActionConstraint : Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata { @@ -141,60 +142,60 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer public partial class ApiDescription { public ApiDescription() { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ParameterDescriptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList SupportedRequestFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList SupportedResponseTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ParameterDescriptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList SupportedRequestFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList SupportedResponseTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApiDescriptionProviderContext { public ApiDescriptionProviderContext(System.Collections.Generic.IReadOnlyList actions) { } - public System.Collections.Generic.IReadOnlyList Actions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Actions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApiParameterDescription { public ApiParameterDescription() { } - public object DefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsRequired { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor ParameterDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterRouteInfo RouteInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource Source { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object DefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsRequired { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor ParameterDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ApiExplorer.ApiParameterRouteInfo RouteInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource Source { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ApiParameterRouteInfo { public ApiParameterRouteInfo() { } - public System.Collections.Generic.IEnumerable Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object DefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsOptional { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IEnumerable Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object DefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsOptional { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ApiRequestFormat { public ApiRequestFormat() { } - public Microsoft.AspNetCore.Mvc.Formatters.IInputFormatter Formatter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string MediaType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Formatters.IInputFormatter Formatter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string MediaType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ApiResponseFormat { public ApiResponseFormat() { } - public Microsoft.AspNetCore.Mvc.Formatters.IOutputFormatter Formatter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string MediaType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Formatters.IOutputFormatter Formatter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string MediaType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ApiResponseType { public ApiResponseType() { } - public System.Collections.Generic.IList ApiResponseFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsDefaultResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList ApiResponseFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsDefaultResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IApiDescriptionProvider { @@ -214,38 +215,38 @@ namespace Microsoft.AspNetCore.Mvc.Filters public partial class ActionExecutedContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ActionExecutedContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters, object controller) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Exception Exception { get { throw null; } set { } } public virtual System.Runtime.ExceptionServices.ExceptionDispatchInfo ExceptionDispatchInfo { get { throw null; } set { } } - public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ActionExecutingContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ActionExecutingContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters, System.Collections.Generic.IDictionary actionArguments, object controller) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual System.Collections.Generic.IDictionary ActionArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Collections.Generic.IDictionary ActionArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public delegate System.Threading.Tasks.Task ActionExecutionDelegate(); public partial class AuthorizationFilterContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public AuthorizationFilterContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ExceptionContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ExceptionContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } public virtual System.Exception Exception { get { throw null; } set { } } public virtual System.Runtime.ExceptionServices.ExceptionDispatchInfo ExceptionDispatchInfo { get { throw null; } set { } } - public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class FilterContext : Microsoft.AspNetCore.Mvc.ActionContext { public FilterContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters) { } - public virtual System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public TMetadata FindEffectivePolicy() where TMetadata : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { throw null; } public bool IsEffectivePolicy(TMetadata policy) where TMetadata : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { throw null; } } @@ -253,24 +254,24 @@ namespace Microsoft.AspNetCore.Mvc.Filters public partial class FilterDescriptor { public FilterDescriptor(Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter, int filterScope) { } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Scope { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Scope { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Diagnostics.DebuggerDisplayAttribute("FilterItem: {Filter}")] public partial class FilterItem { public FilterItem(Microsoft.AspNetCore.Mvc.Filters.FilterDescriptor descriptor) { } public FilterItem(Microsoft.AspNetCore.Mvc.Filters.FilterDescriptor descriptor, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Filters.FilterDescriptor Descriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Filters.FilterDescriptor Descriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class FilterProviderContext { public FilterProviderContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList items) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IActionFilter : Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { @@ -346,35 +347,35 @@ namespace Microsoft.AspNetCore.Mvc.Filters public partial class ResourceExecutedContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ResourceExecutedContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Exception Exception { get { throw null; } set { } } public virtual System.Runtime.ExceptionServices.ExceptionDispatchInfo ExceptionDispatchInfo { get { throw null; } set { } } - public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ResourceExecutingContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ResourceExecutingContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters, System.Collections.Generic.IList valueProviderFactories) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ValueProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ValueProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public delegate System.Threading.Tasks.Task ResourceExecutionDelegate(); public partial class ResultExecutedContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ResultExecutedContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters, Microsoft.AspNetCore.Mvc.IActionResult result, object controller) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Exception Exception { get { throw null; } set { } } public virtual System.Runtime.ExceptionServices.ExceptionDispatchInfo ExceptionDispatchInfo { get { throw null; } set { } } - public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ResultExecutingContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public ResultExecutingContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IList filters, Microsoft.AspNetCore.Mvc.IActionResult result, object controller) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } - public virtual bool Cancel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool Cancel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public delegate System.Threading.Tasks.Task ResultExecutionDelegate(); } @@ -400,13 +401,13 @@ namespace Microsoft.AspNetCore.Mvc.Formatters { public InputFormatterContext(Microsoft.AspNetCore.Http.HttpContext httpContext, string modelName, Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, System.Func readerFactory) { } public InputFormatterContext(Microsoft.AspNetCore.Http.HttpContext httpContext, string modelName, Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, System.Func readerFactory, bool treatEmptyInputAsDefaultValue) { } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Func ReaderFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool TreatEmptyInputAsDefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Func ReaderFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool TreatEmptyInputAsDefaultValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class InputFormatterException : System.Exception { @@ -422,9 +423,9 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public partial class InputFormatterResult { internal InputFormatterResult() { } - public bool HasError { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsModelSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool HasError { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsModelSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Mvc.Formatters.InputFormatterResult Failure() { throw null; } public static System.Threading.Tasks.Task FailureAsync() { throw null; } public static Microsoft.AspNetCore.Mvc.Formatters.InputFormatterResult NoValue() { throw null; } @@ -440,16 +441,16 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public abstract partial class OutputFormatterCanWriteContext { protected OutputFormatterCanWriteContext(Microsoft.AspNetCore.Http.HttpContext httpContext) { } - public virtual Microsoft.Extensions.Primitives.StringSegment ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual bool ContentTypeIsServerDefined { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public virtual object Object { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public virtual System.Type ObjectType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public virtual Microsoft.Extensions.Primitives.StringSegment ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual bool ContentTypeIsServerDefined { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public virtual object Object { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public virtual System.Type ObjectType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } } public partial class OutputFormatterWriteContext : Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext { public OutputFormatterWriteContext(Microsoft.AspNetCore.Http.HttpContext httpContext, System.Func writerFactory, System.Type objectType, object @object) : base (default(Microsoft.AspNetCore.Http.HttpContext)) { } - public virtual System.Func WriterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public virtual System.Func WriterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } } } namespace Microsoft.AspNetCore.Mvc.ModelBinding @@ -458,11 +459,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { public BindingInfo() { } public BindingInfo(Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo other) { } - public string BinderModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string BinderModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Type BinderType { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider PropertyFilterProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func RequestPredicate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider PropertyFilterProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func RequestPredicate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public static Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo GetBindingInfo(System.Collections.Generic.IEnumerable attributes) { throw null; } public static Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo GetBindingInfo(System.Collections.Generic.IEnumerable attributes, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata) { throw null; } public bool TryApplyBindingInfo(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata) { throw null; } @@ -481,10 +482,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public static readonly Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource Services; public static readonly Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource Special; public BindingSource(string id, string displayName, bool isGreedy, bool isFromRequest) { } - public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsFromRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsGreedy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsFromRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsGreedy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool CanAcceptDataFrom(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) { throw null; } public bool Equals(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource other) { throw null; } public override bool Equals(object obj) { throw null; } @@ -495,7 +496,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class CompositeBindingSource : Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource { internal CompositeBindingSource() : base (default(string), default(string), default(bool), default(bool)) { } - public System.Collections.Generic.IEnumerable BindingSources { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable BindingSources { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override bool CanAcceptDataFrom(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) { throw null; } public static Microsoft.AspNetCore.Mvc.ModelBinding.CompositeBindingSource Create(System.Collections.Generic.IEnumerable bindingSources, string displayName) { throw null; } } @@ -503,9 +504,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public readonly partial struct EnumGroupAndName { private readonly object _dummy; + private readonly int _dummyPrimitive; public EnumGroupAndName(string group, System.Func name) { throw null; } public EnumGroupAndName(string group, string name) { throw null; } - public string Group { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Group { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string Name { get { throw null; } } } public partial interface IBinderTypeProviderMetadata : Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata @@ -556,7 +558,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public abstract Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { get; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { get; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { get; } - public virtual System.IServiceProvider Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual System.IServiceProvider Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder CreateBinder(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata); public virtual Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder CreateBinder(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo bindingInfo) { throw null; } } @@ -574,7 +576,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public abstract string ModelName { get; set; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { get; set; } public virtual System.Type ModelType { get { throw null; } } - public string OriginalModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public string OriginalModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public abstract System.Func PropertyFilter { get; set; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult Result { get; set; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateDictionary ValidationState { get; set; } @@ -586,6 +588,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public readonly partial struct NestedScope : System.IDisposable { private readonly object _dummy; + private readonly int _dummyPrimitive; public NestedScope(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext context) { throw null; } public void Dispose() { } } @@ -595,8 +598,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { private readonly object _dummy; private readonly int _dummyPrimitive; - public bool IsModelSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsModelSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Equals(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult other) { throw null; } public override bool Equals(object obj) { throw null; } public static Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingResult Failed() { throw null; } @@ -611,8 +614,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public ModelError(System.Exception exception) { } public ModelError(System.Exception exception, string errorMessage) { } public ModelError(string errorMessage) { } - public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ErrorMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ModelErrorCollection : System.Collections.ObjectModel.Collection { @@ -638,24 +641,24 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public abstract string DisplayName { get; } public abstract string EditFormatString { get; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ElementMetadata { get; } - public System.Type ElementType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type ElementType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract System.Collections.Generic.IEnumerable> EnumGroupedDisplayNamesAndValues { get; } public abstract System.Collections.Generic.IReadOnlyDictionary EnumNamesAndValues { get; } public abstract bool HasNonDefaultEditFormat { get; } - public virtual bool? HasValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual bool? HasValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool HideSurroundingHtml { get; } public abstract bool HtmlEncode { get; } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Identity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Identity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool IsBindingAllowed { get; } public abstract bool IsBindingRequired { get; } - public bool IsCollectionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsComplexType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsCollectionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsComplexType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool IsEnum { get; } - public bool IsEnumerableType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsEnumerableType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool IsFlagsEnum { get; } - public bool IsNullableValueType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsNullableValueType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool IsReadOnly { get; } - public bool IsReferenceOrNullableType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsReferenceOrNullableType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool IsRequired { get; } public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataKind MetadataKind { get { throw null; } } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelBindingMessageProvider ModelBindingMessageProvider { get; } @@ -675,7 +678,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public abstract bool ShowForEdit { get; } public abstract string SimpleDisplayProperty { get; } public abstract string TemplateHint { get; } - public System.Type UnderlyingOrModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type UnderlyingOrModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool ValidateChildren { get; } public abstract System.Collections.Generic.IReadOnlyList ValidatorMetadata { get; } public bool Equals(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata other) { throw null; } @@ -705,8 +708,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public ModelStateDictionary() { } public ModelStateDictionary(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary dictionary) { } public ModelStateDictionary(int maxAllowedErrors) { } - public int Count { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int ErrorCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int Count { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int ErrorCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool HasReachedMaxErrors { get { throw null; } } public bool IsValid { get { throw null; } } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateEntry this[string key] { get { throw null; } } @@ -755,6 +758,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public readonly partial struct KeyEnumerable : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { private readonly object _dummy; + private readonly int _dummyPrimitive; public KeyEnumerable(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary dictionary) { throw null; } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary.KeyEnumerator GetEnumerator() { throw null; } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } @@ -764,8 +768,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial struct KeyEnumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable { private object _dummy; + private int _dummyPrimitive; public KeyEnumerator(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary dictionary, string prefix) { throw null; } - public string Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } object System.Collections.IEnumerator.Current { get { throw null; } } public void Dispose() { } public bool MoveNext() { throw null; } @@ -775,6 +780,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public readonly partial struct PrefixEnumerable : System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable { private readonly object _dummy; + private readonly int _dummyPrimitive; public PrefixEnumerable(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary dictionary, string prefix) { throw null; } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary.Enumerator GetEnumerator() { throw null; } System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() { throw null; } @@ -784,6 +790,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public readonly partial struct ValueEnumerable : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { private readonly object _dummy; + private readonly int _dummyPrimitive; public ValueEnumerable(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary dictionary) { throw null; } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary.ValueEnumerator GetEnumerator() { throw null; } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } @@ -793,8 +800,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial struct ValueEnumerator : System.Collections.Generic.IEnumerator, System.Collections.IEnumerator, System.IDisposable { private object _dummy; + private int _dummyPrimitive; public ValueEnumerator(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary dictionary, string prefix) { throw null; } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateEntry Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateEntry Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } object System.Collections.IEnumerator.Current { get { throw null; } } public void Dispose() { } public bool MoveNext() { throw null; } @@ -804,12 +812,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public abstract partial class ModelStateEntry { protected ModelStateEntry() { } - public string AttemptedValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AttemptedValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.Collections.Generic.IReadOnlyList Children { get; } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelErrorCollection Errors { get { throw null; } } public abstract bool IsContainerNode { get; } - public object RawValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState ValidationState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object RawValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelValidationState ValidationState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateEntry GetModelStateForProperty(string propertyName); } public enum ModelValidationState @@ -831,20 +839,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class ValueProviderFactoryContext { public ValueProviderFactoryContext(Microsoft.AspNetCore.Mvc.ActionContext context) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList ValueProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList ValueProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ValueProviderResult : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.IEquatable { private readonly object _dummy; + private readonly int _dummyPrimitive; public static Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult None; public ValueProviderResult(Microsoft.Extensions.Primitives.StringValues values) { throw null; } public ValueProviderResult(Microsoft.Extensions.Primitives.StringValues values, System.Globalization.CultureInfo culture) { throw null; } - public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string FirstValue { get { throw null; } } public int Length { get { throw null; } } - public Microsoft.Extensions.Primitives.StringValues Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Primitives.StringValues Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Equals(Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult other) { throw null; } public override bool Equals(object obj) { throw null; } public System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } @@ -862,26 +871,27 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata public abstract partial class ModelBindingMessageProvider { protected ModelBindingMessageProvider() { } - public virtual System.Func AttemptedValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func MissingBindRequiredValueAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func MissingKeyOrValueAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func MissingRequestBodyRequiredValueAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func NonPropertyAttemptedValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func NonPropertyUnknownValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func NonPropertyValueMustBeANumberAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func UnknownValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func ValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func ValueMustBeANumberAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Func ValueMustNotBeNullAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual System.Func AttemptedValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func MissingBindRequiredValueAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func MissingKeyOrValueAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func MissingRequestBodyRequiredValueAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func NonPropertyAttemptedValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func NonPropertyUnknownValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func NonPropertyValueMustBeANumberAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func UnknownValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func ValueIsInvalidAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func ValueMustBeANumberAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Func ValueMustNotBeNullAccessor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct ModelMetadataIdentity : System.IEquatable { private readonly object _dummy; - public System.Type ContainerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + private readonly int _dummyPrimitive; + public System.Type ContainerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataKind MetadataKind { get { throw null; } } - public System.Type ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Reflection.ParameterInfo ParameterInfo { get { throw null; } } public System.Reflection.PropertyInfo PropertyInfo { get { throw null; } } public bool Equals(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity other) { throw null; } @@ -906,21 +916,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation public partial class ClientModelValidationContext : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ModelValidationContextBase { public ClientModelValidationContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, System.Collections.Generic.IDictionary attributes) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata), default(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider)) { } - public System.Collections.Generic.IDictionary Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ClientValidatorItem { public ClientValidatorItem() { } public ClientValidatorItem(object validatorMetadata) { } - public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IClientModelValidator Validator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object ValidatorMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IClientModelValidator Validator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object ValidatorMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ClientValidatorProviderContext { public ClientValidatorProviderContext(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata, System.Collections.Generic.IList items) { } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IReadOnlyList ValidatorMetadata { get { throw null; } } } public partial interface IClientModelValidator @@ -950,37 +960,38 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation public partial class ModelValidationContext : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ModelValidationContextBase { public ModelValidationContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, object container, object model) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata), default(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider)) { } - public object Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ModelValidationContextBase { public ModelValidationContextBase(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ModelValidationResult { public ModelValidationResult(string memberName, string message) { } - public string MemberName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string MemberName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ModelValidatorProviderContext { public ModelValidatorProviderContext(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata, System.Collections.Generic.IList items) { } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Results { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IReadOnlyList ValidatorMetadata { get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public partial struct ValidationEntry { private object _dummy; + private int _dummyPrimitive; public ValidationEntry(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, string key, System.Func modelAccessor) { throw null; } public ValidationEntry(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, string key, object model) { throw null; } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public object Model { get { throw null; } } } public partial class ValidationStateDictionary : System.Collections.Generic.ICollection>, System.Collections.Generic.IDictionary, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyDictionary, System.Collections.IEnumerable @@ -1008,18 +1019,18 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation public partial class ValidationStateEntry { public ValidationStateEntry() { } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IValidationStrategy Strategy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressValidation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IValidationStrategy Strategy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressValidation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ValidatorItem { public ValidatorItem() { } public ValidatorItem(object validatorMetadata) { } - public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidator Validator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object ValidatorMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidator Validator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object ValidatorMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.Routing @@ -1027,29 +1038,29 @@ namespace Microsoft.AspNetCore.Mvc.Routing public partial class AttributeRouteInfo { public AttributeRouteInfo() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressLinkGeneration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressPathMatching { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressLinkGeneration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressPathMatching { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UrlActionContext { public UrlActionContext() { } - public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UrlRouteContext { public UrlRouteContext() { } - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Mvc/Mvc.Abstractions/src/ModelBinding/IValueProvider.cs b/src/Mvc/Mvc.Abstractions/src/ModelBinding/IValueProvider.cs index 4e57509298..55d1f63af9 100644 --- a/src/Mvc/Mvc.Abstractions/src/ModelBinding/IValueProvider.cs +++ b/src/Mvc/Mvc.Abstractions/src/ModelBinding/IValueProvider.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// Retrieves a value object using the specified key. /// /// The key of the value object to retrieve. - /// The value object for the specified key. If the exact key is not found, null. + /// The value object for the specified key. If the exact key is not found, . ValueProviderResult GetValue(string key); } } diff --git a/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelStateDictionary.cs b/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelStateDictionary.cs index 53c475d199..48b8b9ee3a 100644 --- a/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelStateDictionary.cs +++ b/src/Mvc/Mvc.Abstractions/src/ModelBinding/ModelStateDictionary.cs @@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding /// tracks the number of model errors added by calls to /// or /// . - /// Once the value of MaxAllowedErrors - 1 is reached, if another attempt is made to add an error, + /// Once the value of MaxAllowedErrors - 1 is reached, if another attempt is made to add an error, /// the error message will be ignored and a will be added. /// /// diff --git a/src/Mvc/Mvc.Analyzers/src/AvoidHtmlPartialAnalyzer.cs b/src/Mvc/Mvc.Analyzers/src/AvoidHtmlPartialAnalyzer.cs index 3563fa525b..c4ba61910d 100644 --- a/src/Mvc/Mvc.Analyzers/src/AvoidHtmlPartialAnalyzer.cs +++ b/src/Mvc/Mvc.Analyzers/src/AvoidHtmlPartialAnalyzer.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; namespace Microsoft.AspNetCore.Mvc.Analyzers { @@ -19,16 +20,9 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers protected override void InitializeWorker(ViewFeaturesAnalyzerContext analyzerContext) { - analyzerContext.Context.RegisterSyntaxNodeAction(context => + analyzerContext.Context.RegisterOperationAction(context => { - var invocationExpression = (InvocationExpressionSyntax)context.Node; - var symbol = context.SemanticModel.GetSymbolInfo(invocationExpression, context.CancellationToken).Symbol; - if (symbol == null || symbol.Kind != SymbolKind.Method) - { - return; - } - - var method = (IMethodSymbol)symbol; + var method = ((IInvocationOperation)context.Operation).TargetMethod; if (!analyzerContext.IsHtmlHelperExtensionMethod(method)) { return; @@ -38,17 +32,17 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers { context.ReportDiagnostic(Diagnostic.Create( SupportedDiagnostic, - invocationExpression.GetLocation(), + context.Operation.Syntax.GetLocation(), new[] { SymbolNames.PartialMethod })); } else if (string.Equals(SymbolNames.RenderPartialMethod, method.Name, StringComparison.Ordinal)) { context.ReportDiagnostic(Diagnostic.Create( SupportedDiagnostic, - invocationExpression.GetLocation(), + context.Operation.Syntax.GetLocation(), new[] { SymbolNames.RenderPartialMethod })); } - }, SyntaxKind.InvocationExpression); + }, OperationKind.Invocation); } } } diff --git a/src/Mvc/Mvc.Analyzers/src/ViewFeaturesAnalyzerContext.cs b/src/Mvc/Mvc.Analyzers/src/ViewFeaturesAnalyzerContext.cs index 096132d67f..6fe12d0b3d 100644 --- a/src/Mvc/Mvc.Analyzers/src/ViewFeaturesAnalyzerContext.cs +++ b/src/Mvc/Mvc.Analyzers/src/ViewFeaturesAnalyzerContext.cs @@ -32,11 +32,6 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers return false; } - if (method.ReceiverType != HtmlHelperType) - { - return false; - } - if (method.ContainingType != HtmlHelperPartialExtensionsType) { return false; diff --git a/src/Mvc/Mvc.Analyzers/test/Infrastructure/MvcTestSource.cs b/src/Mvc/Mvc.Analyzers/test/Infrastructure/MvcTestSource.cs index 244bd263a1..9f2d41ddb7 100644 --- a/src/Mvc/Mvc.Analyzers/test/Infrastructure/MvcTestSource.cs +++ b/src/Mvc/Mvc.Analyzers/test/Infrastructure/MvcTestSource.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Mvc return AppContext.BaseDirectory; } -// https://github.com/aspnet/AspNetCore/issues/9431 +// https://github.com/dotnet/aspnetcore/issues/9431 #pragma warning disable 0618 var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Mvc"); #pragma warning restore 0618 diff --git a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj index 2a6bf81ebb..50068596e0 100644 --- a/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj +++ b/src/Mvc/Mvc.Analyzers/test/Mvc.Analyzers.Test.csproj @@ -6,7 +6,7 @@ Microsoft.AspNetCore.Mvc.Analyzers - + false diff --git a/src/Mvc/Mvc.Analyzers/test/TopLevelParameterNameAnalyzerTest.cs b/src/Mvc/Mvc.Analyzers/test/TopLevelParameterNameAnalyzerTest.cs index b13e1eac9e..5876561098 100644 --- a/src/Mvc/Mvc.Analyzers/test/TopLevelParameterNameAnalyzerTest.cs +++ b/src/Mvc/Mvc.Analyzers/test/TopLevelParameterNameAnalyzerTest.cs @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers Assert.False(result); } - // Test for https://github.com/aspnet/AspNetCore/issues/6945 + // Test for https://github.com/dotnet/aspnetcore/issues/6945 [Fact] public async Task IsProblematicParameter_ReturnsFalse_ForSimpleTypes() { diff --git a/src/Mvc/Mvc.Api.Analyzers/test/Infrastructure/MvcTestSource.cs b/src/Mvc/Mvc.Api.Analyzers/test/Infrastructure/MvcTestSource.cs index 95510e5e46..2423896cc0 100644 --- a/src/Mvc/Mvc.Api.Analyzers/test/Infrastructure/MvcTestSource.cs +++ b/src/Mvc/Mvc.Api.Analyzers/test/Infrastructure/MvcTestSource.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Mvc return AppContext.BaseDirectory; } -// https://github.com/aspnet/AspNetCore/issues/9431 +// https://github.com/dotnet/aspnetcore/issues/9431 #pragma warning disable 0618 var solutionDirectory = TestPathUtilities.GetSolutionRootDirectory("Mvc"); #pragma warning restore 0618 diff --git a/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj b/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj index 5bed22b17f..c79050218f 100644 --- a/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj +++ b/src/Mvc/Mvc.Api.Analyzers/test/Mvc.Api.Analyzers.Test.csproj @@ -5,7 +5,7 @@ Microsoft.AspNetCore.Mvc.Api.Analyzers - + false diff --git a/src/Mvc/Mvc.ApiExplorer/ref/Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs b/src/Mvc/Mvc.ApiExplorer/ref/Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs index 81b46bc384..63c534e213 100644 --- a/src/Mvc/Mvc.ApiExplorer/ref/Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs +++ b/src/Mvc/Mvc.ApiExplorer/ref/Microsoft.AspNetCore.Mvc.ApiExplorer.netcoreapp.cs @@ -11,14 +11,14 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer public partial class ApiDescriptionGroup { public ApiDescriptionGroup(string groupName, System.Collections.Generic.IReadOnlyList items) { } - public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApiDescriptionGroupCollection { public ApiDescriptionGroupCollection(System.Collections.Generic.IReadOnlyList items, int version) { } - public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApiDescriptionGroupCollectionProvider : Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupCollectionProvider { diff --git a/src/Mvc/Mvc.ApiExplorer/src/ApiResponseTypeProvider.cs b/src/Mvc/Mvc.ApiExplorer/src/ApiResponseTypeProvider.cs index bd5b4d0f3a..11d2458456 100644 --- a/src/Mvc/Mvc.ApiExplorer/src/ApiResponseTypeProvider.cs +++ b/src/Mvc/Mvc.ApiExplorer/src/ApiResponseTypeProvider.cs @@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer // 2. When a type is specified, use GetSupportedContentTypes to expand wildcards and get the range of content-types formatters support. // 3. When no formatter supports the specified content-type, use the user specified value as is. This is useful in actions where the user // dictates the content-type. - // e.g. [Produces("application/pdf")] Action() => FileStream("somefile.pdf", "applicaiton/pdf"); + // e.g. [Produces("application/pdf")] Action() => FileStream("somefile.pdf", "application/pdf"); foreach (var apiResponse in responseTypes) { diff --git a/src/Mvc/Mvc.Core/ref/Microsoft.AspNetCore.Mvc.Core.netcoreapp.cs b/src/Mvc/Mvc.Core/ref/Microsoft.AspNetCore.Mvc.Core.netcoreapp.cs index 5da8649bbc..2aaa567743 100644 --- a/src/Mvc/Mvc.Core/ref/Microsoft.AspNetCore.Mvc.Core.netcoreapp.cs +++ b/src/Mvc/Mvc.Core/ref/Microsoft.AspNetCore.Mvc.Core.netcoreapp.cs @@ -39,30 +39,30 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(202)] public partial class AcceptedAtActionResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public AcceptedAtActionResult(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public AcceptedAtActionResult(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(202)] public partial class AcceptedAtRouteResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public AcceptedAtRouteResult(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public AcceptedAtRouteResult(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public AcceptedAtRouteResult(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public AcceptedAtRouteResult(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(202)] public partial class AcceptedResult : Microsoft.AspNetCore.Mvc.ObjectResult { public AcceptedResult() : base (default(object)) { } - public AcceptedResult(string location, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public AcceptedResult(System.Uri locationUri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public AcceptedResult(string location, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public AcceptedResult(System.Uri locationUri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public string Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] @@ -70,12 +70,12 @@ namespace Microsoft.AspNetCore.Mvc { public AcceptVerbsAttribute(string method) { } public AcceptVerbsAttribute(params string[] methods) { } - public System.Collections.Generic.IEnumerable HttpMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable HttpMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } int? Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider.Order { get { throw null; } } string Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider.Template { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int Order { get { throw null; } set { } } - public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public partial class ActionContextAttribute : System.Attribute @@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc public sealed partial class ActionNameAttribute : System.Attribute { public ActionNameAttribute(string name) { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class ActionResult : Microsoft.AspNetCore.Mvc.IActionResult { @@ -98,8 +98,8 @@ namespace Microsoft.AspNetCore.Mvc { public ActionResult(Microsoft.AspNetCore.Mvc.ActionResult result) { } public ActionResult(TValue value) { } - public Microsoft.AspNetCore.Mvc.ActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public TValue Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } Microsoft.AspNetCore.Mvc.IActionResult Microsoft.AspNetCore.Mvc.Infrastructure.IConvertToActionResult.Convert() { throw null; } public static implicit operator Microsoft.AspNetCore.Mvc.ActionResult (Microsoft.AspNetCore.Mvc.ActionResult result) { throw null; } public static implicit operator Microsoft.AspNetCore.Mvc.ActionResult (TValue value) { throw null; } @@ -111,12 +111,12 @@ namespace Microsoft.AspNetCore.Mvc public partial class ApiBehaviorOptions : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { public ApiBehaviorOptions() { } - public System.Collections.Generic.IDictionary ClientErrorMapping { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary ClientErrorMapping { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Func InvalidModelStateResponseFactory { get { throw null; } set { } } - public bool SuppressConsumesConstraintForFormFileParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressInferBindingSourcesForParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressMapClientErrors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressModelStateInvalidFilter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SuppressConsumesConstraintForFormFileParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressInferBindingSourcesForParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressMapClientErrors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressModelStateInvalidFilter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } @@ -129,25 +129,25 @@ namespace Microsoft.AspNetCore.Mvc public sealed partial class ApiConventionMethodAttribute : System.Attribute { public ApiConventionMethodAttribute(System.Type conventionType, string methodName) { } - public System.Type ConventionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type ConventionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class, AllowMultiple=true, Inherited=true)] public sealed partial class ApiConventionTypeAttribute : System.Attribute { public ApiConventionTypeAttribute(System.Type conventionType) { } - public System.Type ConventionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type ConventionType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApiDescriptionActionData { public ApiDescriptionActionData() { } - public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public partial class ApiExplorerSettingsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupNameProvider, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionVisibilityProvider { public ApiExplorerSettingsAttribute() { } - public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IgnoreApi { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IgnoreApi { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public partial class AreaAttribute : Microsoft.AspNetCore.Mvc.Routing.RouteValueAttribute @@ -157,8 +157,8 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(400)] public partial class BadRequestObjectResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public BadRequestObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) : base (default(object)) { } - public BadRequestObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object error) : base (default(object)) { } + public BadRequestObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) : base (default(object)) { } + public BadRequestObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object error) : base (default(object)) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(400)] public partial class BadRequestResult : Microsoft.AspNetCore.Mvc.StatusCodeResult @@ -169,16 +169,16 @@ namespace Microsoft.AspNetCore.Mvc public partial class BindAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider { public BindAttribute(params string[] include) { } - public string[] Include { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string[] Include { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } string Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider.Name { get { throw null; } } - public string Prefix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Prefix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Func PropertyFilter { get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public partial class BindPropertiesAttribute : System.Attribute { public BindPropertiesAttribute() { } - public bool SupportsGet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SupportsGet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public partial class BindPropertyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBinderTypeProviderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IRequestPredicateProvider @@ -187,17 +187,17 @@ namespace Microsoft.AspNetCore.Mvc public System.Type BinderType { get { throw null; } set { } } public virtual Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get { throw null; } protected set { } } System.Func Microsoft.AspNetCore.Mvc.ModelBinding.IRequestPredicateProvider.RequestPredicate { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SupportsGet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SupportsGet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CacheProfile { public CacheProfile() { } - public int? Duration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ResponseCacheLocation? Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? NoStore { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string VaryByHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] VaryByQueryKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? Duration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ResponseCacheLocation? Location { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? NoStore { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string VaryByHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] VaryByQueryKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ChallengeResult : Microsoft.AspNetCore.Mvc.ActionResult { @@ -207,16 +207,16 @@ namespace Microsoft.AspNetCore.Mvc public ChallengeResult(System.Collections.Generic.IList authenticationSchemes, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } public ChallengeResult(string authenticationScheme) { } public ChallengeResult(string authenticationScheme, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } - public System.Collections.Generic.IList AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class ClientErrorData { public ClientErrorData() { } - public string Link { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Title { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Link { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Title { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public enum CompatibilityVersion { @@ -232,8 +232,8 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(409)] public partial class ConflictObjectResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public ConflictObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) : base (default(object)) { } - public ConflictObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object error) : base (default(object)) { } + public ConflictObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) : base (default(object)) { } + public ConflictObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object error) : base (default(object)) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(409)] public partial class ConflictResult : Microsoft.AspNetCore.Mvc.StatusCodeResult @@ -245,7 +245,7 @@ namespace Microsoft.AspNetCore.Mvc { public static readonly int ConsumesActionConstraintOrder; public ConsumesAttribute(string contentType, params string[] otherContentTypes) { } - public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } int Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint.Order { get { throw null; } } public bool Accept(Microsoft.AspNetCore.Mvc.ActionConstraints.ActionConstraintContext context) { throw null; } public void OnResourceExecuted(Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext context) { } @@ -255,9 +255,9 @@ namespace Microsoft.AspNetCore.Mvc public partial class ContentResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult { public ContentResult() { } - public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false, Inherited=true)] @@ -285,43 +285,43 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted(string uri) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted(string uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted(string uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted(System.Uri uri) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted(System.Uri uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedResult Accepted(System.Uri uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, string controllerName) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, string controllerName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object routeValues) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, string controllerName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object routeValues) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtActionResult AcceptedAtAction(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object routeValues) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object routeValues) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute(string routeName) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute(string routeName, object routeValues) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.AcceptedAtRouteResult AcceptedAtRoute(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.BadRequestResult BadRequest() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.BadRequestObjectResult BadRequest([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.BadRequestObjectResult BadRequest([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.BadRequestObjectResult BadRequest([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object error) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.BadRequestObjectResult BadRequest([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object error) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.ChallengeResult Challenge() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] @@ -333,9 +333,9 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.ConflictResult Conflict() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.ConflictObjectResult Conflict([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.ConflictObjectResult Conflict([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.ConflictObjectResult Conflict([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object error) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.ConflictObjectResult Conflict([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object error) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.ContentResult Content(string content) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] @@ -345,21 +345,21 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.ContentResult Content(string content, string contentType, System.Text.Encoding contentEncoding) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedResult Created(string uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedResult Created(string uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedResult Created(System.Uri uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedResult Created(System.Uri uri, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedAtActionResult CreatedAtAction(string actionName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedAtActionResult CreatedAtAction(string actionName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedAtActionResult CreatedAtAction(string actionName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedAtActionResult CreatedAtAction(string actionName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedAtActionResult CreatedAtAction(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedAtActionResult CreatedAtAction(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute(string routeName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute(string routeName, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.CreatedAtRouteResult CreatedAtRoute(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.FileContentResult File(byte[] fileContents, string contentType) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] @@ -429,11 +429,11 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.NotFoundResult NotFound() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.NotFoundObjectResult NotFound([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.NotFoundObjectResult NotFound([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.OkResult Ok() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.OkObjectResult Ok([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.OkObjectResult Ok([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.PhysicalFileResult PhysicalFile(string physicalPath, string contentType) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] @@ -549,9 +549,9 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.SignOutResult SignOut(params string[] authenticationSchemes) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.StatusCodeResult StatusCode([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultStatusCodeAttribute]int statusCode) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.StatusCodeResult StatusCode([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultStatusCodeAttribute] int statusCode) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.ObjectResult StatusCode([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultStatusCodeAttribute]int statusCode, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.ObjectResult StatusCode([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultStatusCodeAttribute] int statusCode, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task TryUpdateModelAsync(object model, System.Type modelType, string prefix) { throw null; } @@ -581,21 +581,21 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.UnauthorizedResult Unauthorized() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult Unauthorized([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.UnauthorizedObjectResult Unauthorized([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.UnprocessableEntityResult UnprocessableEntity() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.UnprocessableEntityObjectResult UnprocessableEntity([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.UnprocessableEntityObjectResult UnprocessableEntity([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.UnprocessableEntityObjectResult UnprocessableEntity([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object error) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.UnprocessableEntityObjectResult UnprocessableEntity([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object error) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem() { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelStateDictionary) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelStateDictionary) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ValidationProblemDetails descriptor) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ValidationProblemDetails descriptor) { throw null; } [Microsoft.AspNetCore.Mvc.NonActionAttribute] - public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem(string detail = null, string instance = null, int? statusCode = default(int?), string title = null, string type = null, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelStateDictionary = null) { throw null; } + public virtual Microsoft.AspNetCore.Mvc.ActionResult ValidationProblem(string detail = null, string instance = null, int? statusCode = default(int?), string title = null, string type = null, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelStateDictionary = null) { throw null; } } public partial class ControllerContext : Microsoft.AspNetCore.Mvc.ActionContext { @@ -612,21 +612,21 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(201)] public partial class CreatedAtActionResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public CreatedAtActionResult(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public CreatedAtActionResult(string actionName, string controllerName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(201)] public partial class CreatedAtRouteResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public CreatedAtRouteResult(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public CreatedAtRouteResult(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public CreatedAtRouteResult(object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public CreatedAtRouteResult(string routeName, object routeValues, [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(201)] @@ -643,53 +643,53 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(201)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(400)] - public static void Create([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object model) { } + public static void Create([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object model) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(200)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(400)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(404)] - public static void Delete([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object id) { } + public static void Delete([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object id) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(204)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(400)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(404)] - public static void Edit([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object id, [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object model) { } + public static void Edit([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object id, [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object model) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(200)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(404)] - public static void Find([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object id) { } + public static void Find([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object id) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(200)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(404)] - public static void Get([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object id) { } + public static void Get([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object id) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(201)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(400)] - public static void Post([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object model) { } + public static void Post([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object model) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(204)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(400)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(404)] - public static void Put([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object id, [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object model) { } + public static void Put([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object id, [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object model) { } [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix)] [Microsoft.AspNetCore.Mvc.ProducesDefaultResponseTypeAttribute] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(204)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(400)] [Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute(404)] - public static void Update([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object id, [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)]object model) { } + public static void Update([Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object id, [Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Any), Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior.Any)] object model) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public partial class DisableRequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public DisableRequestSizeLimitAttribute() { } public bool IsReusable { get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } public partial class EmptyResult : Microsoft.AspNetCore.Mvc.ActionResult @@ -707,11 +707,11 @@ namespace Microsoft.AspNetCore.Mvc public abstract partial class FileResult : Microsoft.AspNetCore.Mvc.ActionResult { protected FileResult(string contentType) { } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnableRangeProcessing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.Net.Http.Headers.EntityTagHeaderValue EntityTag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnableRangeProcessing { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.Net.Http.Headers.EntityTagHeaderValue EntityTag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string FileDownloadName { get { throw null; } set { } } - public System.DateTimeOffset? LastModified { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.DateTimeOffset? LastModified { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class FileStreamResult : Microsoft.AspNetCore.Mvc.FileResult { @@ -728,8 +728,8 @@ namespace Microsoft.AspNetCore.Mvc public ForbidResult(System.Collections.Generic.IList authenticationSchemes, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } public ForbidResult(string authenticationScheme) { } public ForbidResult(string authenticationScheme, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } - public System.Collections.Generic.IList AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } @@ -751,28 +751,28 @@ namespace Microsoft.AspNetCore.Mvc { public FromFormAttribute() { } public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public partial class FromHeaderAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public FromHeaderAttribute() { } public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public partial class FromQueryAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public FromQueryAttribute() { } public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Parameter | System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] public partial class FromRouteAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public FromRouteAttribute() { } public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Parameter, AllowMultiple=false, Inherited=true)] public partial class FromServicesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata @@ -828,16 +828,16 @@ namespace Microsoft.AspNetCore.Mvc public partial class JsonOptions { public JsonOptions() { } - public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Text.Json.JsonSerializerOptions JsonSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class JsonResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult { public JsonResult(object value) { } public JsonResult(object value, object serializerSettings) { } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class LocalRedirectResult : Microsoft.AspNetCore.Mvc.ActionResult @@ -845,19 +845,19 @@ namespace Microsoft.AspNetCore.Mvc public LocalRedirectResult(string localUrl) { } public LocalRedirectResult(string localUrl, bool permanent) { } public LocalRedirectResult(string localUrl, bool permanent, bool preserveMethod) { } - public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string Url { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] public partial class MiddlewareFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public MiddlewareFilterAttribute(System.Type configurationType) { } - public System.Type ConfigurationType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type ConfigurationType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool IsReusable { get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Enum | System.AttributeTargets.Parameter | System.AttributeTargets.Property | System.AttributeTargets.Struct, AllowMultiple=false, Inherited=true)] @@ -867,44 +867,44 @@ namespace Microsoft.AspNetCore.Mvc public ModelBinderAttribute(System.Type binderType) { } public System.Type BinderType { get { throw null; } set { } } public virtual Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get { throw null; } protected set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=false, Inherited=true)] public partial class ModelMetadataTypeAttribute : System.Attribute { public ModelMetadataTypeAttribute(System.Type type) { } - public System.Type MetadataType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type MetadataType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class MvcOptions : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { public MvcOptions() { } - public bool AllowEmptyInputInBodyModelBinding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary CacheProfiles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Conventions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool EnableEndpointRouting { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Filters.FilterCollection Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Formatters.FormatterMappings FormatterMappings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Formatters.FormatterCollection InputFormatters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int MaxIAsyncEnumerableBufferLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowEmptyInputInBodyModelBinding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary CacheProfiles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Conventions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool EnableEndpointRouting { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Filters.FilterCollection Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Formatters.FormatterMappings FormatterMappings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Formatters.FormatterCollection InputFormatters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int MaxIAsyncEnumerableBufferLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int MaxModelBindingCollectionSize { get { throw null; } set { } } public int MaxModelBindingRecursionDepth { get { throw null; } set { } } public int MaxModelValidationErrors { get { throw null; } set { } } public int? MaxValidationDepth { get { throw null; } set { } } - public System.Collections.Generic.IList ModelBinderProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelBindingMessageProvider ModelBindingMessageProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList ModelMetadataDetailsProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList ModelValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Formatters.FormatterCollection OutputFormatters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool RequireHttpsPermanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RespectBrowserAcceptHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ReturnHttpNotAcceptable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? SslPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressAsyncSuffixInActionNames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressImplicitRequiredAttributeForNonNullableReferenceTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressInputFormatterBuffering { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressOutputFormatterBuffering { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ValidateComplexTypesIfChildValidationFails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ValueProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ModelBinderProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelBindingMessageProvider ModelBindingMessageProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList ModelMetadataDetailsProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList ModelValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Formatters.FormatterCollection OutputFormatters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool RequireHttpsPermanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RespectBrowserAcceptHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ReturnHttpNotAcceptable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? SslPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressAsyncSuffixInActionNames { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressImplicitRequiredAttributeForNonNullableReferenceTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressInputFormatterBuffering { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressOutputFormatterBuffering { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ValidateComplexTypesIfChildValidationFails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ValueProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } @@ -931,7 +931,7 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(404)] public partial class NotFoundObjectResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public NotFoundObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } + public NotFoundObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(404)] public partial class NotFoundResult : Microsoft.AspNetCore.Mvc.StatusCodeResult @@ -942,11 +942,11 @@ namespace Microsoft.AspNetCore.Mvc { public ObjectResult(object value) { } public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { get { throw null; } set { } } - public System.Type DeclaredType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Formatters.FormatterCollection Formatters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type DeclaredType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Formatters.FormatterCollection Formatters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } public virtual void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) { } } @@ -971,27 +971,27 @@ namespace Microsoft.AspNetCore.Mvc { public ProblemDetails() { } [System.Text.Json.Serialization.JsonPropertyNameAttribute("detail")] - public string Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Detail { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Text.Json.Serialization.JsonExtensionDataAttribute] - public System.Collections.Generic.IDictionary Extensions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Extensions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Text.Json.Serialization.JsonPropertyNameAttribute("instance")] - public string Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Text.Json.Serialization.JsonPropertyNameAttribute("status")] - public int? Status { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? Status { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Text.Json.Serialization.JsonPropertyNameAttribute("title")] - public string Title { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Title { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Text.Json.Serialization.JsonPropertyNameAttribute("type")] - public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public partial class ProducesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter { public ProducesAttribute(string contentType, params string[] additionalContentTypes) { } public ProducesAttribute(System.Type type) { } - public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int StatusCode { get { throw null; } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void OnResultExecuted(Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext context) { } public virtual void OnResultExecuting(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext context) { } public void SetContentTypes(Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection contentTypes) { } @@ -1001,23 +1001,23 @@ namespace Microsoft.AspNetCore.Mvc { public ProducesDefaultResponseTypeAttribute() { } public ProducesDefaultResponseTypeAttribute(System.Type type) { } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } void Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider.SetContentTypes(Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection contentTypes) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public sealed partial class ProducesErrorResponseTypeAttribute : System.Attribute { public ProducesErrorResponseTypeAttribute(System.Type type) { } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] public partial class ProducesResponseTypeAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { public ProducesResponseTypeAttribute(int statusCode) { } public ProducesResponseTypeAttribute(System.Type type, int statusCode) { } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } void Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider.SetContentTypes(Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection contentTypes) { } } public partial class RedirectResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult @@ -1025,10 +1025,10 @@ namespace Microsoft.AspNetCore.Mvc public RedirectResult(string url) { } public RedirectResult(string url, bool permanent) { } public RedirectResult(string url, bool permanent, bool preserveMethod) { } - public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string Url { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class RedirectToActionResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult @@ -1039,13 +1039,13 @@ namespace Microsoft.AspNetCore.Mvc public RedirectToActionResult(string actionName, string controllerName, object routeValues, bool permanent, bool preserveMethod, string fragment) { } public RedirectToActionResult(string actionName, string controllerName, object routeValues, bool permanent, string fragment) { } public RedirectToActionResult(string actionName, string controllerName, object routeValues, string fragment) { } - public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class RedirectToPageResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult @@ -1059,15 +1059,15 @@ namespace Microsoft.AspNetCore.Mvc public RedirectToPageResult(string pageName, string pageHandler, object routeValues, bool permanent, bool preserveMethod, string fragment) { } public RedirectToPageResult(string pageName, string pageHandler, object routeValues, bool permanent, string fragment) { } public RedirectToPageResult(string pageName, string pageHandler, object routeValues, string fragment) { } - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PageName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PageName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class RedirectToRouteResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.ViewFeatures.IKeepTempDataResult @@ -1079,12 +1079,12 @@ namespace Microsoft.AspNetCore.Mvc public RedirectToRouteResult(string routeName, object routeValues, bool permanent, bool preserveMethod, string fragment) { } public RedirectToRouteResult(string routeName, object routeValues, bool permanent, string fragment) { } public RedirectToRouteResult(string routeName, object routeValues, string fragment) { } - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Permanent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PreserveMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] @@ -1100,7 +1100,7 @@ namespace Microsoft.AspNetCore.Mvc public int MultipartBoundaryLengthLimit { get { throw null; } set { } } public int MultipartHeadersCountLimit { get { throw null; } set { } } public int MultipartHeadersLengthLimit { get { throw null; } set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int ValueCountLimit { get { throw null; } set { } } public int ValueLengthLimit { get { throw null; } set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } @@ -1110,14 +1110,14 @@ namespace Microsoft.AspNetCore.Mvc { public RequestSizeLimitAttribute(long bytes) { } public bool IsReusable { get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, Inherited=true, AllowMultiple=false)] public partial class RequireHttpsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public RequireHttpsAttribute() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool Permanent { get { throw null; } set { } } protected virtual void HandleNonHttpsRequest(Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext filterContext) { } public virtual void OnAuthorization(Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext filterContext) { } @@ -1126,14 +1126,14 @@ namespace Microsoft.AspNetCore.Mvc public partial class ResponseCacheAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public ResponseCacheAttribute() { } - public string CacheProfileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string CacheProfileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int Duration { get { throw null; } set { } } public bool IsReusable { get { throw null; } } public Microsoft.AspNetCore.Mvc.ResponseCacheLocation Location { get { throw null; } set { } } public bool NoStore { get { throw null; } set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string VaryByHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string[] VaryByQueryKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string VaryByHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string[] VaryByQueryKeys { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } public Microsoft.AspNetCore.Mvc.CacheProfile GetCacheProfile(Microsoft.AspNetCore.Mvc.MvcOptions options) { throw null; } } @@ -1148,9 +1148,9 @@ namespace Microsoft.AspNetCore.Mvc { public RouteAttribute(string template) { } int? Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider.Order { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int Order { get { throw null; } set { } } - public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class SerializableError : System.Collections.Generic.Dictionary { @@ -1162,18 +1162,18 @@ namespace Microsoft.AspNetCore.Mvc public partial class ServiceFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public ServiceFilterAttribute(System.Type type) { } - public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ServiceType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ServiceType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } public partial class SignInResult : Microsoft.AspNetCore.Mvc.ActionResult { public SignInResult(string authenticationScheme, System.Security.Claims.ClaimsPrincipal principal) { } public SignInResult(string authenticationScheme, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } - public string AuthenticationScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticationScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } @@ -1184,16 +1184,16 @@ namespace Microsoft.AspNetCore.Mvc public SignOutResult(System.Collections.Generic.IList authenticationSchemes, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } public SignOutResult(string authenticationScheme) { } public SignOutResult(string authenticationScheme, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { } - public System.Collections.Generic.IList AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class StatusCodeResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IClientErrorActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult { - public StatusCodeResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultStatusCodeAttribute]int statusCode) { } + public StatusCodeResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultStatusCodeAttribute] int statusCode) { } int? Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult.StatusCode { get { throw null; } } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override void ExecuteResult(Microsoft.AspNetCore.Mvc.ActionContext context) { } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] @@ -1201,16 +1201,16 @@ namespace Microsoft.AspNetCore.Mvc public partial class TypeFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public TypeFilterAttribute(System.Type type) { } - public object[] Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ImplementationType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object[] Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ImplementationType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsReusable { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(401)] public partial class UnauthorizedObjectResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public UnauthorizedObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object value) : base (default(object)) { } + public UnauthorizedObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object value) : base (default(object)) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(401)] public partial class UnauthorizedResult : Microsoft.AspNetCore.Mvc.StatusCodeResult @@ -1220,8 +1220,8 @@ namespace Microsoft.AspNetCore.Mvc [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(422)] public partial class UnprocessableEntityObjectResult : Microsoft.AspNetCore.Mvc.ObjectResult { - public UnprocessableEntityObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) : base (default(object)) { } - public UnprocessableEntityObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute]object error) : base (default(object)) { } + public UnprocessableEntityObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) : base (default(object)) { } + public UnprocessableEntityObjectResult([Microsoft.AspNetCore.Mvc.Infrastructure.ActionResultObjectValueAttribute] object error) : base (default(object)) { } } [Microsoft.AspNetCore.Mvc.Infrastructure.DefaultStatusCodeAttribute(422)] public partial class UnprocessableEntityResult : Microsoft.AspNetCore.Mvc.StatusCodeResult @@ -1265,14 +1265,14 @@ namespace Microsoft.AspNetCore.Mvc public ValidationProblemDetails(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { } public ValidationProblemDetails(System.Collections.Generic.IDictionary errors) { } [System.Text.Json.Serialization.JsonPropertyNameAttribute("errors")] - public System.Collections.Generic.IDictionary Errors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Errors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class VirtualFileResult : Microsoft.AspNetCore.Mvc.FileResult { public VirtualFileResult(string fileName, Microsoft.Net.Http.Headers.MediaTypeHeaderValue contentType) : base (default(string)) { } public VirtualFileResult(string fileName, string contentType) : base (default(string)) { } public string FileName { get { throw null; } set { } } - public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } } @@ -1282,7 +1282,7 @@ namespace Microsoft.AspNetCore.Mvc.ActionConstraints public abstract partial class ActionMethodSelectorAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata { protected ActionMethodSelectorAttribute() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool Accept(Microsoft.AspNetCore.Mvc.ActionConstraints.ActionConstraintContext context) { throw null; } public abstract bool IsValidForRequest(Microsoft.AspNetCore.Routing.RouteContext routeContext, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor action); } @@ -1301,7 +1301,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer public sealed partial class ApiConventionNameMatchAttribute : System.Attribute { public ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior matchBehavior) { } - public Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior MatchBehavior { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior MatchBehavior { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum ApiConventionNameMatchBehavior { @@ -1313,13 +1313,13 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer public sealed partial class ApiConventionResult { public ApiConventionResult(System.Collections.Generic.IReadOnlyList responseMetadataProviders) { } - public System.Collections.Generic.IReadOnlyList ResponseMetadataProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList ResponseMetadataProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Parameter, AllowMultiple=false, Inherited=false)] public sealed partial class ApiConventionTypeMatchAttribute : System.Attribute { public ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior matchBehavior) { } - public Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior MatchBehavior { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior MatchBehavior { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum ApiConventionTypeMatchBehavior { @@ -1363,25 +1363,25 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public ActionModel(Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel other) { } public ActionModel(System.Reflection.MethodInfo actionMethod, System.Collections.Generic.IReadOnlyList attributes) { } - public System.Reflection.MethodInfo ActionMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel ApiExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.MethodInfo ActionMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel ApiExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string DisplayName { get { throw null; } } - public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Reflection.MemberInfo Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.MemberInfo { get { throw null; } } string Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.Name { get { throw null; } } - public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.IOutboundParameterTransformer RouteParameterTransformer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Selectors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.IOutboundParameterTransformer RouteParameterTransformer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Selectors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApiConventionApplicationModelConvention : Microsoft.AspNetCore.Mvc.ApplicationModels.IActionModelConvention { public ApiConventionApplicationModelConvention(Microsoft.AspNetCore.Mvc.ProducesErrorResponseTypeAttribute defaultErrorResponseType) { } - public Microsoft.AspNetCore.Mvc.ProducesErrorResponseTypeAttribute DefaultErrorResponseType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ProducesErrorResponseTypeAttribute DefaultErrorResponseType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Apply(Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) { } protected virtual bool ShouldApply(Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel action) { throw null; } } @@ -1389,8 +1389,8 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public ApiExplorerModel() { } public ApiExplorerModel(Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel other) { } - public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? IsVisible { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string GroupName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? IsVisible { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ApiVisibilityConvention : Microsoft.AspNetCore.Mvc.ApplicationModels.IActionModelConvention { @@ -1402,29 +1402,29 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels public partial class ApplicationModel : Microsoft.AspNetCore.Mvc.ApplicationModels.IApiExplorerModel, Microsoft.AspNetCore.Mvc.ApplicationModels.IFilterModel, Microsoft.AspNetCore.Mvc.ApplicationModels.IPropertyModel { public ApplicationModel() { } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel ApiExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Controllers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel ApiExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Controllers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ApplicationModelProviderContext { public ApplicationModelProviderContext(System.Collections.Generic.IEnumerable controllerTypes) { } - public System.Collections.Generic.IEnumerable ControllerTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModel Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable ControllerTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModel Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class AttributeRouteModel { public AttributeRouteModel() { } public AttributeRouteModel(Microsoft.AspNetCore.Mvc.ApplicationModels.AttributeRouteModel other) { } public AttributeRouteModel(Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider templateProvider) { } - public Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider Attribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider Attribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool IsAbsoluteTemplate { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressLinkGeneration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SuppressPathMatching { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressLinkGeneration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SuppressPathMatching { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public static Microsoft.AspNetCore.Mvc.ApplicationModels.AttributeRouteModel CombineAttributeRouteModel(Microsoft.AspNetCore.Mvc.ApplicationModels.AttributeRouteModel left, Microsoft.AspNetCore.Mvc.ApplicationModels.AttributeRouteModel right) { throw null; } public static string CombineTemplates(string prefix, string template) { throw null; } public static bool IsOverridePattern(string template) { throw null; } @@ -1448,20 +1448,20 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public ControllerModel(Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel other) { } public ControllerModel(System.Reflection.TypeInfo controllerType, System.Collections.Generic.IReadOnlyList attributes) { } - public System.Collections.Generic.IList Actions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel ApiExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModel Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ControllerProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Reflection.TypeInfo ControllerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Actions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ApiExplorerModel ApiExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ApplicationModel Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ControllerProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Reflection.TypeInfo ControllerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string DisplayName { get { throw null; } } - public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Reflection.MemberInfo Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.MemberInfo { get { throw null; } } string Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.Name { get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Selectors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Selectors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IActionModelConvention { @@ -1528,11 +1528,11 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public ParameterModel(Microsoft.AspNetCore.Mvc.ApplicationModels.ParameterModel other) : base (default(System.Type), default(System.Collections.Generic.IReadOnlyList)) { } public ParameterModel(System.Reflection.ParameterInfo parameterInfo, System.Collections.Generic.IReadOnlyList attributes) : base (default(System.Type), default(System.Collections.Generic.IReadOnlyList)) { } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ActionModel Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new System.Collections.Generic.IReadOnlyList Attributes { get { throw null; } } public string DisplayName { get { throw null; } } System.Reflection.MemberInfo Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.MemberInfo { get { throw null; } } - public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string ParameterName { get { throw null; } set { } } public new System.Collections.Generic.IDictionary Properties { get { throw null; } } } @@ -1540,11 +1540,11 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { protected ParameterModelBase(Microsoft.AspNetCore.Mvc.ApplicationModels.ParameterModelBase other) { } protected ParameterModelBase(System.Type parameterType, System.Collections.Generic.IReadOnlyList attributes) { } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } - public System.Type ParameterType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } + public System.Type ParameterType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Diagnostics.DebuggerDisplayAttribute("PropertyModel: Name={PropertyName}")] public partial class PropertyModel : Microsoft.AspNetCore.Mvc.ApplicationModels.ParameterModelBase, Microsoft.AspNetCore.Mvc.ApplicationModels.IBindingModel, Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel, Microsoft.AspNetCore.Mvc.ApplicationModels.IPropertyModel @@ -1552,10 +1552,10 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels public PropertyModel(Microsoft.AspNetCore.Mvc.ApplicationModels.PropertyModel other) : base (default(System.Type), default(System.Collections.Generic.IReadOnlyList)) { } public PropertyModel(System.Reflection.PropertyInfo propertyInfo, System.Collections.Generic.IReadOnlyList attributes) : base (default(System.Type), default(System.Collections.Generic.IReadOnlyList)) { } public new System.Collections.Generic.IReadOnlyList Attributes { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } System.Reflection.MemberInfo Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.MemberInfo { get { throw null; } } public new System.Collections.Generic.IDictionary Properties { get { throw null; } } - public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string PropertyName { get { throw null; } set { } } } public partial class RouteTokenTransformerConvention : Microsoft.AspNetCore.Mvc.ApplicationModels.IActionModelConvention @@ -1568,9 +1568,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public SelectorModel() { } public SelectorModel(Microsoft.AspNetCore.Mvc.ApplicationModels.SelectorModel other) { } - public System.Collections.Generic.IList ActionConstraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.AttributeRouteModel AttributeRouteModel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList EndpointMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ActionConstraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.AttributeRouteModel AttributeRouteModel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList EndpointMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.ApplicationParts @@ -1584,7 +1584,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts public sealed partial class ApplicationPartAttribute : System.Attribute { public ApplicationPartAttribute(string assemblyName) { } - public string AssemblyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AssemblyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class ApplicationPartFactory { @@ -1595,21 +1595,21 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts public partial class ApplicationPartManager { public ApplicationPartManager() { } - public System.Collections.Generic.IList ApplicationParts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList FeatureProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ApplicationParts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList FeatureProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void PopulateFeature(TFeature feature) { } } public partial class AssemblyPart : Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPart, Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationPartTypeProvider { public AssemblyPart(System.Reflection.Assembly assembly) { } - public System.Reflection.Assembly Assembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Reflection.Assembly Assembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string Name { get { throw null; } } public System.Collections.Generic.IEnumerable Types { get { throw null; } } } public partial class DefaultApplicationPartFactory : Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartFactory { public DefaultApplicationPartFactory() { } - public static Microsoft.AspNetCore.Mvc.ApplicationParts.DefaultApplicationPartFactory Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public static Microsoft.AspNetCore.Mvc.ApplicationParts.DefaultApplicationPartFactory Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override System.Collections.Generic.IEnumerable GetApplicationParts(System.Reflection.Assembly assembly) { throw null; } public static System.Collections.Generic.IEnumerable GetDefaultApplicationParts(System.Reflection.Assembly assembly) { throw null; } } @@ -1644,7 +1644,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts public sealed partial class RelatedAssemblyAttribute : System.Attribute { public RelatedAssemblyAttribute(string assemblyFileName) { } - public string AssemblyFileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AssemblyFileName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static System.Collections.Generic.IReadOnlyList GetRelatedAssemblies(System.Reflection.Assembly assembly, bool throwOnError) { throw null; } } } @@ -1661,10 +1661,10 @@ namespace Microsoft.AspNetCore.Mvc.Authorization public AuthorizeFilter(Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider policyProvider, System.Collections.Generic.IEnumerable authorizeData) { } public AuthorizeFilter(System.Collections.Generic.IEnumerable authorizeData) { } public AuthorizeFilter(string policy) { } - public System.Collections.Generic.IEnumerable AuthorizeData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable AuthorizeData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } bool Microsoft.AspNetCore.Mvc.Filters.IFilterFactory.IsReusable { get { throw null; } } - public Microsoft.AspNetCore.Authorization.AuthorizationPolicy Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider PolicyProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authorization.AuthorizationPolicy Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authorization.IAuthorizationPolicyProvider PolicyProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Microsoft.AspNetCore.Mvc.Filters.IFilterFactory.CreateInstance(System.IServiceProvider serviceProvider) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task OnAuthorizationAsync(Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext context) { throw null; } @@ -1676,11 +1676,11 @@ namespace Microsoft.AspNetCore.Mvc.Controllers public partial class ControllerActionDescriptor : Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor { public ControllerActionDescriptor() { } - public virtual string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo ControllerTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual string ActionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo ControllerTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string DisplayName { get { throw null; } set { } } - public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ControllerActivatorProvider : Microsoft.AspNetCore.Mvc.Controllers.IControllerActivatorProvider { @@ -1691,12 +1691,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers public partial class ControllerBoundPropertyDescriptor : Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor, Microsoft.AspNetCore.Mvc.Infrastructure.IPropertyInfoParameterDescriptor { public ControllerBoundPropertyDescriptor() { } - public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ControllerFeature { public ControllerFeature() { } - public System.Collections.Generic.IList Controllers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList Controllers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ControllerFeatureProvider : Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationFeatureProvider, Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationFeatureProvider { @@ -1707,7 +1707,7 @@ namespace Microsoft.AspNetCore.Mvc.Controllers public partial class ControllerParameterDescriptor : Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor, Microsoft.AspNetCore.Mvc.Infrastructure.IParameterInfoParameterDescriptor { public ControllerParameterDescriptor() { } - public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IControllerActivator { @@ -1748,208 +1748,208 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterAction"; public AfterActionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteData routeData) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterActionFilterOnActionExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnActionExecuted"; public AfterActionFilterOnActionExecutedEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext ActionExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext ActionExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterActionFilterOnActionExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnActionExecuting"; public AfterActionFilterOnActionExecutingEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext actionExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext ActionExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext ActionExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterActionFilterOnActionExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnActionExecution"; public AfterActionFilterOnActionExecutionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext ActionExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext ActionExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterActionResultEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterActionResult"; public AfterActionResultEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.IActionResult result) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterAuthorizationFilterOnAuthorizationEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnAuthorization"; public AfterAuthorizationFilterOnAuthorizationEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext authorizationContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext AuthorizationContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext AuthorizationContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterControllerActionMethodEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterControllerActionMethod"; public AfterControllerActionMethodEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IReadOnlyDictionary arguments, object controller, Microsoft.AspNetCore.Mvc.IActionResult result) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterExceptionFilterOnExceptionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnException"; public AfterExceptionFilterOnExceptionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ExceptionContext exceptionContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ExceptionContext ExceptionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ExceptionContext ExceptionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterResourceFilterOnResourceExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnResourceExecuted"; public AfterResourceFilterOnResourceExecutedEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext resourceExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext ResourceExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext ResourceExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterResourceFilterOnResourceExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnResourceExecuting"; public AfterResourceFilterOnResourceExecutingEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext resourceExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext ResourceExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext ResourceExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterResourceFilterOnResourceExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnResourceExecution"; public AfterResourceFilterOnResourceExecutionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext resourceExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext ResourceExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext ResourceExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterResultFilterOnResultExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnResultExecuted"; public AfterResultFilterOnResultExecutedEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext resultExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext ResultExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext ResultExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterResultFilterOnResultExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnResultExecuting"; public AfterResultFilterOnResultExecutingEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext resultExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext ResultExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext ResultExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterResultFilterOnResultExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnResultExecution"; public AfterResultFilterOnResultExecutionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext resultExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext ResultExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext ResultExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeActionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeAction"; public BeforeActionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteData routeData) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeActionFilterOnActionExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnActionExecuted"; public BeforeActionFilterOnActionExecutedEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext actionExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext ActionExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext ActionExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforeActionFilterOnActionExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnActionExecuting"; public BeforeActionFilterOnActionExecutingEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext actionExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext ActionExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext ActionExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforeActionFilterOnActionExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnActionExecution"; public BeforeActionFilterOnActionExecutionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext actionExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext ActionExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext ActionExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforeActionResultEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeActionResult"; public BeforeActionResultEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.IActionResult result) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeAuthorizationFilterOnAuthorizationEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnAuthorization"; public BeforeAuthorizationFilterOnAuthorizationEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext authorizationContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext AuthorizationContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext AuthorizationContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforeControllerActionMethodEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeControllerActionMethod"; public BeforeControllerActionMethodEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IReadOnlyDictionary actionArguments, object controller) { } - public System.Collections.Generic.IReadOnlyDictionary ActionArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary ActionArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected sealed override int Count { get { throw null; } } protected sealed override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } @@ -1957,71 +1957,71 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnException"; public BeforeExceptionFilterOnException(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ExceptionContext exceptionContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ExceptionContext ExceptionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ExceptionContext ExceptionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforeResourceFilterOnResourceExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnResourceExecuted"; public BeforeResourceFilterOnResourceExecutedEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext resourceExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext ResourceExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext ResourceExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeResourceFilterOnResourceExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnResourceExecuting"; public BeforeResourceFilterOnResourceExecutingEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext resourceExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext ResourceExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext ResourceExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeResourceFilterOnResourceExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnResourceExecution"; public BeforeResourceFilterOnResourceExecutionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext resourceExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext ResourceExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext ResourceExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeResultFilterOnResultExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnResultExecuted"; public BeforeResultFilterOnResultExecutedEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext resultExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext ResultExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext ResultExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeResultFilterOnResultExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnResultExecuting"; public BeforeResultFilterOnResultExecutingEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext resultExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext ResultExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext ResultExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeResultFilterOnResultExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnResultExecution"; public BeforeResultFilterOnResultExecutionEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext resultExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata filter) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext ResultExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext ResultExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class EventData : System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyList>, System.Collections.IEnumerable { @@ -2038,7 +2038,7 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics { private object _dummy; private int _dummyPrimitive; - public System.Collections.Generic.KeyValuePair Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.KeyValuePair Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } object System.Collections.IEnumerator.Current { get { throw null; } } public void Dispose() { } public bool MoveNext() { throw null; } @@ -2052,7 +2052,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters public abstract partial class ActionFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter { protected ActionFilterAttribute() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void OnActionExecuted(Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext context) { } public virtual void OnActionExecuting(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext context) { } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -2066,7 +2066,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters public abstract partial class ExceptionFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAsyncExceptionFilter, Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { protected ExceptionFilterAttribute() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void OnException(Microsoft.AspNetCore.Mvc.Filters.ExceptionContext context) { } public virtual System.Threading.Tasks.Task OnExceptionAsync(Microsoft.AspNetCore.Mvc.Filters.ExceptionContext context) { throw null; } } @@ -2094,7 +2094,7 @@ namespace Microsoft.AspNetCore.Mvc.Filters public abstract partial class ResultFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter { protected ResultFilterAttribute() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void OnResultExecuted(Microsoft.AspNetCore.Mvc.Filters.ResultExecutedContext context) { } public virtual void OnResultExecuting(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext context) { } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -2123,14 +2123,14 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public partial class HttpNoContentOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.IOutputFormatter { public HttpNoContentOutputFormatter() { } - public bool TreatNullValueAsNoContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool TreatNullValueAsNoContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool CanWriteResult(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext context) { throw null; } public System.Threading.Tasks.Task WriteAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context) { throw null; } } public abstract partial class InputFormatter : Microsoft.AspNetCore.Mvc.ApiExplorer.IApiRequestFormatMetadataProvider, Microsoft.AspNetCore.Mvc.Formatters.IInputFormatter { protected InputFormatter() { } - public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection SupportedMediaTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection SupportedMediaTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool CanRead(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) { throw null; } protected virtual bool CanReadType(System.Type type) { throw null; } protected virtual object GetDefaultValueForType(System.Type modelType) { throw null; } @@ -2142,6 +2142,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public readonly partial struct MediaType { private readonly object _dummy; + private readonly int _dummyPrimitive; public MediaType(Microsoft.Extensions.Primitives.StringSegment mediaType) { throw null; } public MediaType(string mediaType) { throw null; } public MediaType(string mediaType, int offset, int? length) { throw null; } @@ -2151,10 +2152,10 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public bool MatchesAllSubTypes { get { throw null; } } public bool MatchesAllSubTypesWithoutSuffix { get { throw null; } } public bool MatchesAllTypes { get { throw null; } } - public Microsoft.Extensions.Primitives.StringSegment SubType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.Primitives.StringSegment SubTypeSuffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.Primitives.StringSegment SubTypeWithoutSuffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.Primitives.StringSegment Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Primitives.StringSegment SubType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.Primitives.StringSegment SubTypeSuffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.Primitives.StringSegment SubTypeWithoutSuffix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.Primitives.StringSegment Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Mvc.Formatters.MediaTypeSegmentWithQuality CreateMediaTypeSegmentWithQuality(string mediaType, int start) { throw null; } public static System.Text.Encoding GetEncoding(Microsoft.Extensions.Primitives.StringSegment mediaType) { throw null; } public static System.Text.Encoding GetEncoding(string mediaType) { throw null; } @@ -2177,14 +2178,14 @@ namespace Microsoft.AspNetCore.Mvc.Formatters private readonly object _dummy; private readonly int _dummyPrimitive; public MediaTypeSegmentWithQuality(Microsoft.Extensions.Primitives.StringSegment mediaType, double quality) { throw null; } - public Microsoft.Extensions.Primitives.StringSegment MediaType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public double Quality { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Primitives.StringSegment MediaType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public double Quality { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string ToString() { throw null; } } public abstract partial class OutputFormatter : Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseTypeMetadataProvider, Microsoft.AspNetCore.Mvc.Formatters.IOutputFormatter { protected OutputFormatter() { } - public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection SupportedMediaTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection SupportedMediaTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual bool CanWriteResult(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext context) { throw null; } protected virtual bool CanWriteType(System.Type type) { throw null; } public virtual System.Collections.Generic.IReadOnlyList GetSupportedContentTypes(string contentType, System.Type objectType) { throw null; } @@ -2209,14 +2210,14 @@ namespace Microsoft.AspNetCore.Mvc.Formatters { public SystemTextJsonInputFormatter(Microsoft.AspNetCore.Mvc.JsonOptions options, Microsoft.Extensions.Logging.ILogger logger) { } Microsoft.AspNetCore.Mvc.Formatters.InputFormatterExceptionPolicy Microsoft.AspNetCore.Mvc.Formatters.IInputFormatterExceptionPolicy.ExceptionPolicy { get { throw null; } } - public System.Text.Json.JsonSerializerOptions SerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Text.Json.JsonSerializerOptions SerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public sealed override System.Threading.Tasks.Task ReadRequestBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context, System.Text.Encoding encoding) { throw null; } } public partial class SystemTextJsonOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter { public SystemTextJsonOutputFormatter(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } - public System.Text.Json.JsonSerializerOptions SerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Text.Json.JsonSerializerOptions SerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public sealed override System.Threading.Tasks.Task WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context, System.Text.Encoding selectedEncoding) { throw null; } } @@ -2225,7 +2226,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters protected static readonly System.Text.Encoding UTF16EncodingLittleEndian; protected static readonly System.Text.Encoding UTF8EncodingWithoutBOM; protected TextInputFormatter() { } - public System.Collections.Generic.IList SupportedEncodings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList SupportedEncodings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override System.Threading.Tasks.Task ReadRequestBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) { throw null; } public abstract System.Threading.Tasks.Task ReadRequestBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context, System.Text.Encoding encoding); protected System.Text.Encoding SelectCharacterEncoding(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) { throw null; } @@ -2233,7 +2234,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public abstract partial class TextOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.OutputFormatter { protected TextOutputFormatter() { } - public System.Collections.Generic.IList SupportedEncodings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList SupportedEncodings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Text.Encoding SelectCharacterEncoding(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context) { throw null; } public override System.Threading.Tasks.Task WriteAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context) { throw null; } public sealed override System.Threading.Tasks.Task WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context) { throw null; } @@ -2250,8 +2251,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure public partial class ActionDescriptorCollection { public ActionDescriptorCollection(System.Collections.Generic.IReadOnlyList items, int version) { } - public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class ActionDescriptorCollectionProvider : Microsoft.AspNetCore.Mvc.Infrastructure.IActionDescriptorCollectionProvider { @@ -2278,16 +2279,16 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure { public CompatibilitySwitch(string name) { } public CompatibilitySwitch(string name, TValue initialValue) { } - public bool IsValueSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsValueSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } object Microsoft.AspNetCore.Mvc.Infrastructure.ICompatibilitySwitch.Value { get { throw null; } set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public TValue Value { get { throw null; } set { } } } public abstract partial class ConfigureCompatibilityOptions : Microsoft.Extensions.Options.IPostConfigureOptions where TOptions : class, System.Collections.Generic.IEnumerable { protected ConfigureCompatibilityOptions(Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.Extensions.Options.IOptions compatibilityOptions) { } protected abstract System.Collections.Generic.IReadOnlyDictionary DefaultValues { get; } - protected Microsoft.AspNetCore.Mvc.CompatibilityVersion Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.CompatibilityVersion Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual void PostConfigure(string name, TOptions options) { } } public partial class ContentResultExecutor : Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor @@ -2305,7 +2306,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure public sealed partial class DefaultStatusCodeAttribute : System.Attribute { public DefaultStatusCodeAttribute(int statusCode) { } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class FileContentResultExecutor : Microsoft.AspNetCore.Mvc.Infrastructure.FileResultExecutorBase, Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor { @@ -2317,7 +2318,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure { protected const int BufferSize = 65536; public FileResultExecutorBase(Microsoft.Extensions.Logging.ILogger logger) { } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected static Microsoft.Extensions.Logging.ILogger CreateLogger(Microsoft.Extensions.Logging.ILoggerFactory factory) { throw null; } protected virtual (Microsoft.Net.Http.Headers.RangeItemHeaderValue range, long rangeLength, bool serveBody) SetHeadersAndLog(Microsoft.AspNetCore.Mvc.ActionContext context, Microsoft.AspNetCore.Mvc.FileResult result, long? fileLength, bool enableRangeProcessing, System.DateTimeOffset? lastModified = default(System.DateTimeOffset?), Microsoft.Net.Http.Headers.EntityTagHeaderValue etag = null) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -2416,16 +2417,16 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure public partial class MvcCompatibilityOptions { public MvcCompatibilityOptions() { } - public Microsoft.AspNetCore.Mvc.CompatibilityVersion CompatibilityVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.CompatibilityVersion CompatibilityVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ObjectResultExecutor : Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor { [System.ObsoleteAttribute("This constructor is obsolete and will be removed in a future release.")] public ObjectResultExecutor(Microsoft.AspNetCore.Mvc.Infrastructure.OutputFormatterSelector formatterSelector, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public ObjectResultExecutor(Microsoft.AspNetCore.Mvc.Infrastructure.OutputFormatterSelector formatterSelector, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.Extensions.Options.IOptions mvcOptions) { } - protected Microsoft.AspNetCore.Mvc.Infrastructure.OutputFormatterSelector FormatterSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected System.Func WriterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.Infrastructure.OutputFormatterSelector FormatterSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected System.Func WriterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext context, Microsoft.AspNetCore.Mvc.ObjectResult result) { throw null; } } public abstract partial class OutputFormatterSelector @@ -2444,9 +2445,9 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure protected partial class FileMetadata { public FileMetadata() { } - public bool Exists { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.DateTimeOffset LastModified { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long Length { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Exists { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.DateTimeOffset LastModified { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long Length { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } public abstract partial class ProblemDetailsFactory @@ -2496,12 +2497,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class BindingBehaviorAttribute : System.Attribute { public BindingBehaviorAttribute(Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior behavior) { } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior Behavior { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior Behavior { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class BindingSourceValueProvider : Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider { public BindingSourceValueProvider(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) { } - protected Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract bool ContainsPrefix(string prefix); public virtual Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider Filter(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) { throw null; } public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult GetValue(string key); @@ -2579,7 +2580,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class FormValueProvider : Microsoft.AspNetCore.Mvc.ModelBinding.BindingSourceValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IEnumerableValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider { public FormValueProvider(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource, Microsoft.AspNetCore.Http.IFormCollection values, System.Globalization.CultureInfo culture) : base (default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource)) { } - public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.AspNetCore.Mvc.ModelBinding.PrefixContainer PrefixContainer { get { throw null; } } public override bool ContainsPrefix(string prefix) { throw null; } public virtual System.Collections.Generic.IDictionary GetKeysFromPrefix(string prefix) { throw null; } @@ -2631,7 +2632,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public abstract partial class JQueryValueProvider : Microsoft.AspNetCore.Mvc.ModelBinding.BindingSourceValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IEnumerableValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IKeyRewriterValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider { protected JQueryValueProvider(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource, System.Collections.Generic.IDictionary values, System.Globalization.CultureInfo culture) : base (default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource)) { } - public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.AspNetCore.Mvc.ModelBinding.PrefixContainer PrefixContainer { get { throw null; } } public override bool ContainsPrefix(string prefix) { throw null; } public Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider Filter() { throw null; } @@ -2641,10 +2642,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class ModelAttributes { internal ModelAttributes() { } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList ParameterAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList ParameterAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes GetAttributesForParameter(System.Reflection.ParameterInfo parameterInfo) { throw null; } public static Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes GetAttributesForParameter(System.Reflection.ParameterInfo parameterInfo, System.Type modelType) { throw null; } public static Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes GetAttributesForProperty(System.Type type, System.Reflection.PropertyInfo property) { throw null; } @@ -2659,9 +2660,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class ModelBinderFactoryContext { public ModelBinderFactoryContext() { } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object CacheToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingInfo BindingInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object CacheToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class ModelBinderProviderExtensions { @@ -2688,7 +2689,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class ParameterBinder { public ParameterBinder(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider modelMetadataProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinderFactory modelBinderFactory, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IObjectModelValidator validator, Microsoft.Extensions.Options.IOptions mvcOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task BindModelAsync(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder modelBinder, Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider valueProvider, Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor parameter, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, object value) { throw null; } } @@ -2701,7 +2702,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class QueryStringValueProvider : Microsoft.AspNetCore.Mvc.ModelBinding.BindingSourceValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IEnumerableValueProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider { public QueryStringValueProvider(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource, Microsoft.AspNetCore.Http.IQueryCollection values, System.Globalization.CultureInfo culture) : base (default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource)) { } - public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.AspNetCore.Mvc.ModelBinding.PrefixContainer PrefixContainer { get { throw null; } } public override bool ContainsPrefix(string prefix) { throw null; } public virtual System.Collections.Generic.IDictionary GetKeysFromPrefix(string prefix) { throw null; } @@ -2716,7 +2717,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { public RouteValueProvider(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource, Microsoft.AspNetCore.Routing.RouteValueDictionary values) : base (default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource)) { } public RouteValueProvider(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource, Microsoft.AspNetCore.Routing.RouteValueDictionary values, System.Globalization.CultureInfo culture) : base (default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource)) { } - protected System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected System.Globalization.CultureInfo Culture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.AspNetCore.Mvc.ModelBinding.PrefixContainer PrefixContainer { get { throw null; } } public override bool ContainsPrefix(string key) { throw null; } public override Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult GetValue(string key) { throw null; } @@ -2730,8 +2731,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding { public SuppressChildValidationMetadataProvider(string fullTypeName) { } public SuppressChildValidationMetadataProvider(System.Type type) { } - public string FullTypeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FullTypeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void CreateValidationMetadata(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ValidationMetadataProviderContext context) { } } public partial class UnsupportedContentTypeException : System.Exception @@ -2741,7 +2742,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding public partial class UnsupportedContentTypeFilter : Microsoft.AspNetCore.Mvc.Filters.IActionFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public UnsupportedContentTypeFilter() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void OnActionExecuted(Microsoft.AspNetCore.Mvc.Filters.ActionExecutedContext context) { } public void OnActionExecuting(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext context) { } } @@ -2824,8 +2825,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders public CollectionModelBinder(Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder elementBinder, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public CollectionModelBinder(Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder elementBinder, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, bool allowValidatingTopLevelNodes) { } public CollectionModelBinder(Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder elementBinder, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, bool allowValidatingTopLevelNodes, Microsoft.AspNetCore.Mvc.MvcOptions mvcOptions) { } - protected Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder ElementBinder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder ElementBinder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected void AddErrorIfBindingRequired(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext bindingContext) { } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task BindModelAsync(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext bindingContext) { throw null; } @@ -2968,44 +2969,44 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata public partial class BindingMetadata { public BindingMetadata() { } - public string BinderModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string BinderModelName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Type BinderType { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsBindingAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsBindingRequired { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? IsReadOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsBindingAllowed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsBindingRequired { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? IsReadOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelBindingMessageProvider ModelBindingMessageProvider { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider PropertyFilterProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider PropertyFilterProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class BindingMetadataProviderContext { public BindingMetadataProviderContext(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity key, Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes attributes) { } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadata BindingMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList ParameterAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadata BindingMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList ParameterAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class BindingSourceMetadataProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IBindingMetadataProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IMetadataDetailsProvider { public BindingSourceMetadataProvider(System.Type type, Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) { } - public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void CreateBindingMetadata(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadataProviderContext context) { } } public partial class DefaultMetadataDetails { public DefaultMetadataDetails(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity key, Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes attributes) { } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadata BindingMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ContainerMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DisplayMetadata DisplayMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes ModelAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata[] Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func PropertyGetter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action PropertySetter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ValidationMetadata ValidationMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadata BindingMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ContainerMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DisplayMetadata DisplayMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes ModelAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata[] Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func PropertyGetter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action PropertySetter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ValidationMetadata ValidationMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DefaultModelBindingMessageProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelBindingMessageProvider { @@ -3088,8 +3089,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata { public DefaultModelMetadataProvider(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ICompositeMetadataDetailsProvider detailsProvider) { } public DefaultModelMetadataProvider(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ICompositeMetadataDetailsProvider detailsProvider, Microsoft.Extensions.Options.IOptions optionsAccessor) { } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ICompositeMetadataDetailsProvider DetailsProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelBindingMessageProvider ModelBindingMessageProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ICompositeMetadataDetailsProvider DetailsProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelBindingMessageProvider ModelBindingMessageProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected virtual Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata CreateModelMetadata(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultMetadataDetails entry) { throw null; } protected virtual Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultMetadataDetails CreateParameterDetails(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity key) { throw null; } protected virtual Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultMetadataDetails[] CreatePropertyDetails(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity key) { throw null; } @@ -3103,39 +3104,39 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata public partial class DisplayMetadata { public DisplayMetadata() { } - public System.Collections.Generic.IDictionary AdditionalValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool ConvertEmptyStringToNull { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string DataTypeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary AdditionalValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool ConvertEmptyStringToNull { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string DataTypeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func Description { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string DisplayFormatString { get { throw null; } set { } } public System.Func DisplayFormatStringProvider { get { throw null; } set { } } - public System.Func DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string EditFormatString { get { throw null; } set { } } public System.Func EditFormatStringProvider { get { throw null; } set { } } - public System.Collections.Generic.IEnumerable> EnumGroupedDisplayNamesAndValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IReadOnlyDictionary EnumNamesAndValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HasNonDefaultEditFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HideSurroundingHtml { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HtmlEncode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsEnum { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsFlagsEnum { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IEnumerable> EnumGroupedDisplayNamesAndValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IReadOnlyDictionary EnumNamesAndValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HasNonDefaultEditFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HideSurroundingHtml { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HtmlEncode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsEnum { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsFlagsEnum { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string NullDisplayText { get { throw null; } set { } } public System.Func NullDisplayTextProvider { get { throw null; } set { } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func Placeholder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShowForDisplay { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ShowForEdit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SimpleDisplayProperty { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string TemplateHint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func Placeholder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShowForDisplay { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ShowForEdit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SimpleDisplayProperty { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string TemplateHint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DisplayMetadataProviderContext { public DisplayMetadataProviderContext(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity key, Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes attributes) { } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DisplayMetadata DisplayMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DisplayMetadata DisplayMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ExcludeBindingMetadataProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IBindingMetadataProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IMetadataDetailsProvider { @@ -3168,21 +3169,21 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata public partial class ValidationMetadata { public ValidationMetadata() { } - public bool? HasValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? IsRequired { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IPropertyValidationFilter PropertyValidationFilter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? ValidateChildren { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList ValidatorMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool? HasValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? IsRequired { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IPropertyValidationFilter PropertyValidationFilter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? ValidateChildren { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList ValidatorMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ValidationMetadataProviderContext { public ValidationMetadataProviderContext(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity key, Microsoft.AspNetCore.Mvc.ModelBinding.ModelAttributes attributes) { } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList ParameterAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ValidationMetadata ValidationMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList ParameterAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList PropertyAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList TypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ValidationMetadata ValidationMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation @@ -3195,13 +3196,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation public partial class CompositeClientModelValidatorProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IClientModelValidatorProvider { public CompositeClientModelValidatorProvider(System.Collections.Generic.IEnumerable providers) { } - public System.Collections.Generic.IReadOnlyList ValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList ValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void CreateValidators(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientValidatorProviderContext context) { } } public partial class CompositeModelValidatorProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider { public CompositeModelValidatorProvider(System.Collections.Generic.IList providers) { } - public System.Collections.Generic.IList ValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void CreateValidators(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ModelValidatorProviderContext context) { } } public partial interface IMetadataBasedModelValidatorProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider @@ -3227,20 +3228,20 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation { public ValidationVisitor(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider validatorProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidatorCache validatorCache, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateDictionary validationState) { } [System.ObsoleteAttribute("This property is deprecated and is no longer used by the runtime.")] - public bool AllowShortCircuitingValidationWhenNoValidatorsArePresent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidatorCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected object Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ActionContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowShortCircuitingValidationWhenNoValidatorsArePresent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidatorCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected object Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ActionContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int? MaxValidationDepth { get { throw null; } set { } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IValidationStrategy Strategy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ValidateComplexTypesIfChildValidationFails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateDictionary ValidationState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider ValidatorProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IValidationStrategy Strategy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ValidateComplexTypesIfChildValidationFails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateDictionary ValidationState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider ValidatorProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected virtual Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationStateEntry GetValidationEntry(object model) { throw null; } protected virtual void SuppressValidation(string key) { } public bool Validate(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, string key, object model) { throw null; } @@ -3254,6 +3255,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation protected readonly partial struct StateManager : System.IDisposable { private readonly object _dummy; + private readonly int _dummyPrimitive; public StateManager(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor visitor, object newModel) { throw null; } public void Dispose() { } public static Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.StateManager Recurse(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor visitor, string key, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, object model, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IValidationStrategy strategy) { throw null; } @@ -3277,11 +3279,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing { public HttpMethodAttribute(System.Collections.Generic.IEnumerable httpMethods) { } public HttpMethodAttribute(System.Collections.Generic.IEnumerable httpMethods, string template) { } - public System.Collections.Generic.IEnumerable HttpMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable HttpMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } int? Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider.Order { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public int Order { get { throw null; } set { } } - public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Template { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IActionHttpMethodProvider { @@ -3311,8 +3313,8 @@ namespace Microsoft.AspNetCore.Mvc.Routing public abstract partial class RouteValueAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteValueProvider { protected RouteValueAttribute(string routeKey, string routeValue) { } - public string RouteKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RouteValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string RouteKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RouteValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class UrlHelper : Microsoft.AspNetCore.Mvc.Routing.UrlHelperBase { @@ -3327,8 +3329,8 @@ namespace Microsoft.AspNetCore.Mvc.Routing public abstract partial class UrlHelperBase : Microsoft.AspNetCore.Mvc.IUrlHelper { protected UrlHelperBase(Microsoft.AspNetCore.Mvc.ActionContext actionContext) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract string Action(Microsoft.AspNetCore.Mvc.Routing.UrlActionContext actionContext); public virtual string Content(string contentPath) { throw null; } protected string GenerateUrl(string protocol, string host, string path) { throw null; } diff --git a/src/Mvc/Mvc.Core/src/ActionConstraints/HttpMethodActionConstraint.cs b/src/Mvc/Mvc.Core/src/ActionConstraints/HttpMethodActionConstraint.cs index a8a462da7e..6ee65d9f8b 100644 --- a/src/Mvc/Mvc.Core/src/ActionConstraints/HttpMethodActionConstraint.cs +++ b/src/Mvc/Mvc.Core/src/ActionConstraints/HttpMethodActionConstraint.cs @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.Mvc.ActionConstraints { /// - /// The implementation of used to enforce + /// The implementation of used to enforce /// HTTP method filtering when MVC is used with legacy /// support. The can be used to determine /// the set of HTTP methods supported by an action. diff --git a/src/Mvc/Mvc.Core/src/ApiConventionMethodAttribute.cs b/src/Mvc/Mvc.Core/src/ApiConventionMethodAttribute.cs index 8efb21d871..452cd81941 100644 --- a/src/Mvc/Mvc.Core/src/ApiConventionMethodAttribute.cs +++ b/src/Mvc/Mvc.Core/src/ApiConventionMethodAttribute.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// API conventions are used to influence the output of ApiExplorer. /// can be used to specify an exact convention method that applies - /// to an action. for details about applying conventions at + /// to an action. for details about applying conventions at /// the assembly or controller level. /// /// @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// Conventions must be static types. Methods in a convention are /// matched to an action method using rules specified by - /// that may be applied to a method name or it's parameters and + /// that may be applied to a method name or its parameters and /// that are applied to parameters. /// /// diff --git a/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs b/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs index e546a258ea..20e3936d11 100644 --- a/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs +++ b/src/Mvc/Mvc.Core/src/ApiConventionTypeAttribute.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Mvc /// API conventions are used to influence the output of ApiExplorer. /// Conventions must be static types. Methods in a convention are /// matched to an action method using rules specified by - /// that may be applied to a method name or it's parameters and + /// that may be applied to a method name or its parameters and /// that are applied to parameters. /// /// @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// Conventions must be static types. Methods in a convention are /// matched to an action method using rules specified by - /// that may be applied to a method name or it's parameters and + /// that may be applied to a method name or its parameters and /// that are applied to parameters. /// /// diff --git a/src/Mvc/Mvc.Core/src/ApiExplorer/ApiConventionNameMatchBehavior.cs b/src/Mvc/Mvc.Core/src/ApiExplorer/ApiConventionNameMatchBehavior.cs index b4775fbf05..2d4ed01d93 100644 --- a/src/Mvc/Mvc.Core/src/ApiExplorer/ApiConventionNameMatchBehavior.cs +++ b/src/Mvc/Mvc.Core/src/ApiExplorer/ApiConventionNameMatchBehavior.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer public enum ApiConventionNameMatchBehavior { /// - /// Matches any name. Use this if the parameter or method name does not need to be matched. + /// Matches any name. Use this if the parameter does not need to be matched. /// Any, @@ -36,4 +36,4 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer /// Suffix, } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs b/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs index fae18d4481..88f8ce93f4 100644 --- a/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs +++ b/src/Mvc/Mvc.Core/src/ApplicationModels/ApplicationModelFactory.cs @@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels attributeRoutingConfigurationErrors); } - if (attributeRoutingConfigurationErrors.Any()) + if (attributeRoutingConfigurationErrors.Count > 0) { var message = CreateAttributeRoutingAggregateErrorMessage(attributeRoutingConfigurationErrors.Values); @@ -114,13 +114,13 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels } var namedRoutedErrors = ValidateNamedAttributeRoutedActions(actionsByRouteName); - if (namedRoutedErrors.Any()) + if (namedRoutedErrors.Count > 0) { var message = CreateAttributeRoutingAggregateErrorMessage(namedRoutedErrors); throw new InvalidOperationException(message); } - if (routeTemplateErrors.Any()) + if (routeTemplateErrors.Count > 0) { var message = CreateAttributeRoutingAggregateErrorMessage(routeTemplateErrors); throw new InvalidOperationException(message); @@ -131,9 +131,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels } private static void ReplaceAttributeRouteTokens( - ControllerModel controller, - ActionModel action, - SelectorModel selector, + ControllerModel controller, + ActionModel action, + SelectorModel selector, List errors) { if (selector.AttributeRouteModel == null) @@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { "action", action.ActionName }, { "controller", controller.ControllerName }, }; - + foreach (var kvp in action.RouteValues) { routeValues.TryAdd(kvp.Key, kvp.Value); @@ -186,7 +186,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels } private static void AddActionToMethodInfoMap( - Dictionary> actionsByMethod, + Dictionary> actionsByMethod, ActionModel action, SelectorModel selector) { @@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels // we compare it against the rest of the templates that have that same name // associated. // The moment we find one that is different we report the whole group to the - // user in the error message so that he can see the different actions and the + // user in the error message so that they can see the different actions and the // different templates for a given named attribute route. var template = actions[0].selector.AttributeRouteModel.Template; diff --git a/src/Mvc/Mvc.Core/src/BindPropertyAttribute.cs b/src/Mvc/Mvc.Core/src/BindPropertyAttribute.cs index 0760f0aa03..434a3166f9 100644 --- a/src/Mvc/Mvc.Core/src/BindPropertyAttribute.cs +++ b/src/Mvc/Mvc.Core/src/BindPropertyAttribute.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Core; using Microsoft.AspNetCore.Mvc.ModelBinding; @@ -83,7 +84,7 @@ namespace Microsoft.AspNetCore.Mvc private static bool IsNonGetRequest(ActionContext context) { - return !string.Equals(context.HttpContext.Request.Method, "GET", StringComparison.OrdinalIgnoreCase); + return !HttpMethods.IsGet(context.HttpContext.Request.Method); } } } diff --git a/src/Mvc/Mvc.Core/src/ControllerBase.cs b/src/Mvc/Mvc.Core/src/ControllerBase.cs index 90282b41a0..0c1179c805 100644 --- a/src/Mvc/Mvc.Core/src/ControllerBase.cs +++ b/src/Mvc/Mvc.Core/src/ControllerBase.cs @@ -1260,6 +1260,9 @@ namespace Microsoft.AspNetCore.Mvc /// The with the contents of the file. /// The Content-Type of the file. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType) => File(fileStream, contentType, fileDownloadName: null); @@ -1274,6 +1277,9 @@ namespace Microsoft.AspNetCore.Mvc /// The Content-Type of the file. /// Set to true to enable range requests processing. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, bool enableRangeProcessing) => File(fileStream, contentType, fileDownloadName: null, enableRangeProcessing: enableRangeProcessing); @@ -1289,6 +1295,9 @@ namespace Microsoft.AspNetCore.Mvc /// The Content-Type of the file. /// The suggested file name. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) => new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName }; @@ -1305,6 +1314,9 @@ namespace Microsoft.AspNetCore.Mvc /// The suggested file name. /// Set to true to enable range requests processing. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName, bool enableRangeProcessing) => new FileStreamResult(fileStream, contentType) @@ -1324,6 +1336,9 @@ namespace Microsoft.AspNetCore.Mvc /// The of when the file was last modified. /// The associated with the file. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) { @@ -1346,6 +1361,9 @@ namespace Microsoft.AspNetCore.Mvc /// The associated with the file. /// Set to true to enable range requests processing. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) { @@ -1369,6 +1387,9 @@ namespace Microsoft.AspNetCore.Mvc /// The of when the file was last modified. /// The associated with the file. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag) { @@ -1393,6 +1414,9 @@ namespace Microsoft.AspNetCore.Mvc /// The associated with the file. /// Set to true to enable range requests processing. /// The created for the response. + /// + /// The parameter is disposed after the response is sent. + /// [NonAction] public virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName, DateTimeOffset? lastModified, EntityTagHeaderValue entityTag, bool enableRangeProcessing) { @@ -1848,7 +1872,7 @@ namespace Microsoft.AspNetCore.Mvc /// /// Creates an that produces a response. /// - /// The value for .. + /// The value for . /// The value for . /// The value for . /// The value for . diff --git a/src/Mvc/Mvc.Core/src/Controllers/ControllerFeatureProvider.cs b/src/Mvc/Mvc.Core/src/Controllers/ControllerFeatureProvider.cs index 6b5a3616d2..caff2fc22b 100644 --- a/src/Mvc/Mvc.Core/src/Controllers/ControllerFeatureProvider.cs +++ b/src/Mvc/Mvc.Core/src/Controllers/ControllerFeatureProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Mvc.Controllers /// Determines if a given is a controller. /// /// The candidate. - /// true if the type is a controller; otherwise false. + /// if the type is a controller; otherwise . protected virtual bool IsController(TypeInfo typeInfo) { if (!typeInfo.IsClass) diff --git a/src/Mvc/Mvc.Core/src/DependencyInjection/ApiBehaviorOptionsSetup.cs b/src/Mvc/Mvc.Core/src/DependencyInjection/ApiBehaviorOptionsSetup.cs index 4cbd1a2dba..f51b5ade2e 100644 --- a/src/Mvc/Mvc.Core/src/DependencyInjection/ApiBehaviorOptionsSetup.cs +++ b/src/Mvc/Mvc.Core/src/DependencyInjection/ApiBehaviorOptionsSetup.cs @@ -42,7 +42,10 @@ namespace Microsoft.Extensions.DependencyInjection } else { - result = new ObjectResult(problemDetails); + result = new ObjectResult(problemDetails) + { + StatusCode = problemDetails.Status, + }; } result.ContentTypes.Add("application/problem+json"); result.ContentTypes.Add("application/problem+xml"); diff --git a/src/Mvc/Mvc.Core/src/FileContentResult.cs b/src/Mvc/Mvc.Core/src/FileContentResult.cs index 0c33859001..b289f20413 100644 --- a/src/Mvc/Mvc.Core/src/FileContentResult.cs +++ b/src/Mvc/Mvc.Core/src/FileContentResult.cs @@ -27,10 +27,6 @@ namespace Microsoft.AspNetCore.Mvc public FileContentResult(byte[] fileContents, string contentType) : this(fileContents, MediaTypeHeaderValue.Parse(contentType)) { - if (fileContents == null) - { - throw new ArgumentNullException(nameof(fileContents)); - } } /// @@ -80,4 +76,4 @@ namespace Microsoft.AspNetCore.Mvc return executor.ExecuteAsync(context, this); } } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.Core/src/Filters/FilterCollection.cs b/src/Mvc/Mvc.Core/src/Filters/FilterCollection.cs index b5ea9a26c1..bb0f56ef9f 100644 --- a/src/Mvc/Mvc.Core/src/Filters/FilterCollection.cs +++ b/src/Mvc/Mvc.Core/src/Filters/FilterCollection.cs @@ -10,10 +10,10 @@ namespace Microsoft.AspNetCore.Mvc.Filters public class FilterCollection : Collection { /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . - /// An representing the added type. + /// Type representing a . + /// A representing the added type. /// /// Filter instances will be created using /// . @@ -25,10 +25,10 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . - /// An representing the added type. + /// Type representing a . + /// A representing the added type. /// /// Filter instances will be created using /// . @@ -45,11 +45,11 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . + /// Type representing a . /// The order of the added filter. - /// An representing the added type. + /// A representing the added type. /// /// Filter instances will be created using /// . @@ -61,11 +61,11 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . + /// Type representing a . /// The order of the added filter. - /// An representing the added type. + /// A representing the added type. /// /// Filter instances will be created using /// . @@ -92,10 +92,10 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . - /// An representing the added service type. + /// Type representing a . + /// A representing the added service type. /// /// Filter instances will be created through dependency injection. Use /// to register a service that will be created via @@ -107,10 +107,10 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . - /// An representing the added service type. + /// Type representing a . + /// A representing the added service type. /// /// Filter instances will be created through dependency injection. Use /// to register a service that will be created via @@ -127,11 +127,11 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . + /// Type representing a . /// The order of the added filter. - /// An representing the added service type. + /// A representing the added service type. /// /// Filter instances will be created through dependency injection. Use /// to register a service that will be created via @@ -143,11 +143,11 @@ namespace Microsoft.AspNetCore.Mvc.Filters } /// - /// Adds a type representing an . + /// Adds a type representing a . /// - /// Type representing an . + /// Type representing a . /// The order of the added filter. - /// An representing the added service type. + /// A representing the added service type. /// /// Filter instances will be created through dependency injection. Use /// to register a service that will be created via diff --git a/src/Mvc/Mvc.Core/src/Formatters/MediaTypeCollection.cs b/src/Mvc/Mvc.Core/src/Formatters/MediaTypeCollection.cs index b5b52f3ebb..a596862b36 100644 --- a/src/Mvc/Mvc.Core/src/Formatters/MediaTypeCollection.cs +++ b/src/Mvc/Mvc.Core/src/Formatters/MediaTypeCollection.cs @@ -50,8 +50,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters /// Removes the first occurrence of a specific media type from the . /// /// - /// true if is successfully removed; otherwise, false. - /// This method also returns false if was not found in the original + /// if is successfully removed; otherwise, . + /// This method also returns if was not found in the original /// . public bool Remove(MediaTypeHeaderValue item) { diff --git a/src/Mvc/Mvc.Core/src/Formatters/TranscodingReadStream.cs b/src/Mvc/Mvc.Core/src/Formatters/TranscodingReadStream.cs index 6361039ad7..7771093e89 100644 --- a/src/Mvc/Mvc.Core/src/Formatters/TranscodingReadStream.cs +++ b/src/Mvc/Mvc.Core/src/Formatters/TranscodingReadStream.cs @@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Json // Overflow buffer is always empty when we get here and we can use it's full length to write contents to. Utf8.FromUtf16(_charBuffer, _overflowBuffer.Array, out var overFlowChars, out var overflowBytes, isFinalBlock: false); - Debug.Assert(overflowBytes > 0 && overFlowChars > 0, "We expect writes to the overflow buffer to always succeed since it is large enough to accomodate at least one char."); + Debug.Assert(overflowBytes > 0 && overFlowChars > 0, "We expect writes to the overflow buffer to always succeed since it is large enough to accommodate at least one char."); _charBuffer = _charBuffer.Slice(overFlowChars); diff --git a/src/Mvc/Mvc.Core/src/Infrastructure/AsyncEnumerableReader.cs b/src/Mvc/Mvc.Core/src/Infrastructure/AsyncEnumerableReader.cs index 846e8f19d5..3d4679d89b 100644 --- a/src/Mvc/Mvc.Core/src/Infrastructure/AsyncEnumerableReader.cs +++ b/src/Mvc/Mvc.Core/src/Infrastructure/AsyncEnumerableReader.cs @@ -5,7 +5,6 @@ using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Diagnostics; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Core; @@ -17,8 +16,6 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson namespace Microsoft.AspNetCore.Mvc.Infrastructure #endif { - using ReaderFunc = Func, Task>; - /// /// Type that reads an instance into a /// generic collection instance. @@ -34,8 +31,8 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure nameof(ReadInternal), BindingFlags.NonPublic | BindingFlags.Instance); - private readonly ConcurrentDictionary _asyncEnumerableConverters = - new ConcurrentDictionary(); + private readonly ConcurrentDictionary>> _asyncEnumerableConverters = + new ConcurrentDictionary>>(); private readonly MvcOptions _mvcOptions; /// @@ -48,37 +45,39 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure } /// - /// Reads a into an . + /// Attempts to produces a delagate that reads a into an . /// - /// The to read. - /// The . - public Task ReadAsync(IAsyncEnumerable value) + /// The type to read. + /// A delegate that when awaited reads the . + /// when is an instance of , othwerise . + public bool TryGetReader(Type type, out Func> reader) { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - var type = value.GetType(); - if (!_asyncEnumerableConverters.TryGetValue(type, out var result)) + if (!_asyncEnumerableConverters.TryGetValue(type, out reader)) { var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(type, typeof(IAsyncEnumerable<>)); - Debug.Assert(enumerableType != null); + if (enumerableType is null) + { + // Not an IAsyncEnumerable. Cache this result so we avoid reflection the next time we see this type. + reader = null; + _asyncEnumerableConverters.TryAdd(type, reader); + } + else + { + var enumeratedObjectType = enumerableType.GetGenericArguments()[0]; - var enumeratedObjectType = enumerableType.GetGenericArguments()[0]; + var converter = (Func>)Converter + .MakeGenericMethod(enumeratedObjectType) + .CreateDelegate(typeof(Func>), this); - var converter = (ReaderFunc)Converter - .MakeGenericMethod(enumeratedObjectType) - .CreateDelegate(typeof(ReaderFunc), this); - - _asyncEnumerableConverters.TryAdd(type, converter); - result = converter; + reader = converter; + _asyncEnumerableConverters.TryAdd(type, reader); + } } - return result(value); + return reader != null; } - private async Task ReadInternal(IAsyncEnumerable value) + private async Task ReadInternal(object value) { var asyncEnumerable = (IAsyncEnumerable)value; var result = new List(); diff --git a/src/Mvc/Mvc.Core/src/Infrastructure/FileResultExecutorBase.cs b/src/Mvc/Mvc.Core/src/Infrastructure/FileResultExecutorBase.cs index 48ad5f3ad9..cc6acf5ad3 100644 --- a/src/Mvc/Mvc.Core/src/Infrastructure/FileResultExecutorBase.cs +++ b/src/Mvc/Mvc.Core/src/Infrastructure/FileResultExecutorBase.cs @@ -260,7 +260,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure PreconditionState matchFoundState, PreconditionState matchNotFoundState) { - if (etagHeader != null && etagHeader.Any()) + if (etagHeader?.Count > 0) { var state = matchNotFoundState; foreach (var entityTag in etagHeader) diff --git a/src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs b/src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs index 689604162a..0fad09d57e 100644 --- a/src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs +++ b/src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -19,7 +20,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure /// public class ObjectResultExecutor : IActionResultExecutor { - private readonly AsyncEnumerableReader _asyncEnumerableReader; + private readonly AsyncEnumerableReader _asyncEnumerableReaderFactory; /// /// Creates a new . @@ -68,7 +69,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure WriterFactory = writerFactory.CreateWriter; Logger = loggerFactory.CreateLogger(); var options = mvcOptions?.Value ?? throw new ArgumentNullException(nameof(mvcOptions)); - _asyncEnumerableReader = new AsyncEnumerableReader(options); + _asyncEnumerableReaderFactory = new AsyncEnumerableReader(options); } /// @@ -117,19 +118,19 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure var value = result.Value; - if (value is IAsyncEnumerable asyncEnumerable) + if (value != null && _asyncEnumerableReaderFactory.TryGetReader(value.GetType(), out var reader)) { - return ExecuteAsyncEnumerable(context, result, asyncEnumerable); + return ExecuteAsyncEnumerable(context, result, value, reader); } return ExecuteAsyncCore(context, result, objectType, value); } - private async Task ExecuteAsyncEnumerable(ActionContext context, ObjectResult result, IAsyncEnumerable asyncEnumerable) + private async Task ExecuteAsyncEnumerable(ActionContext context, ObjectResult result, object asyncEnumerable, Func> reader) { Log.BufferingAsyncEnumerable(Logger, asyncEnumerable); - var enumerated = await _asyncEnumerableReader.ReadAsync(asyncEnumerable); + var enumerated = await reader(asyncEnumerable); await ExecuteAsyncCore(context, result, enumerated.GetType(), enumerated); } @@ -194,7 +195,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure "Buffering IAsyncEnumerable instance of type '{Type}'."); } - public static void BufferingAsyncEnumerable(ILogger logger, IAsyncEnumerable asyncEnumerable) + public static void BufferingAsyncEnumerable(ILogger logger, object asyncEnumerable) => _bufferingAsyncEnumerable(logger, asyncEnumerable.GetType().FullName, null); } } diff --git a/src/Mvc/Mvc.Core/src/Infrastructure/SystemTextJsonResultExecutor.cs b/src/Mvc/Mvc.Core/src/Infrastructure/SystemTextJsonResultExecutor.cs index 176279550c..1a4960ba5d 100644 --- a/src/Mvc/Mvc.Core/src/Infrastructure/SystemTextJsonResultExecutor.cs +++ b/src/Mvc/Mvc.Core/src/Infrastructure/SystemTextJsonResultExecutor.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure private readonly JsonOptions _options; private readonly ILogger _logger; - private readonly AsyncEnumerableReader _asyncEnumerableReader; + private readonly AsyncEnumerableReader _asyncEnumerableReaderFactory; public SystemTextJsonResultExecutor( IOptions options, @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure { _options = options.Value; _logger = logger; - _asyncEnumerableReader = new AsyncEnumerableReader(mvcOptions.Value); + _asyncEnumerableReaderFactory = new AsyncEnumerableReader(mvcOptions.Value); } public async Task ExecuteAsync(ActionContext context, JsonResult result) @@ -76,10 +76,10 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure try { var value = result.Value; - if (value is IAsyncEnumerable asyncEnumerable) + if (value != null && _asyncEnumerableReaderFactory.TryGetReader(value.GetType(), out var reader)) { - Log.BufferingAsyncEnumerable(_logger, asyncEnumerable); - value = await _asyncEnumerableReader.ReadAsync(asyncEnumerable); + Log.BufferingAsyncEnumerable(_logger, value); + value = await reader(value); } var type = value?.GetType() ?? typeof(object); @@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure _jsonResultExecuting(logger, type, null); } - public static void BufferingAsyncEnumerable(ILogger logger, IAsyncEnumerable asyncEnumerable) + public static void BufferingAsyncEnumerable(ILogger logger, object asyncEnumerable) => _bufferingAsyncEnumerable(logger, asyncEnumerable.GetType().FullName, null); } } diff --git a/src/Mvc/Mvc.Core/src/ObjectResult.cs b/src/Mvc/Mvc.Core/src/ObjectResult.cs index a5a0323089..c85dfcc4ab 100644 --- a/src/Mvc/Mvc.Core/src/ObjectResult.cs +++ b/src/Mvc/Mvc.Core/src/ObjectResult.cs @@ -54,14 +54,21 @@ namespace Microsoft.AspNetCore.Mvc throw new ArgumentNullException(nameof(context)); } + if (Value is ProblemDetails details) + { + if (details.Status != null && StatusCode == null) + { + StatusCode = details.Status; + } + else if (details.Status == null && StatusCode != null) + { + details.Status = StatusCode; + } + } + if (StatusCode.HasValue) { context.HttpContext.Response.StatusCode = StatusCode.Value; - - if (Value is ProblemDetails details && !details.Status.HasValue) - { - details.Status = StatusCode.Value; - } } } } diff --git a/src/Mvc/Mvc.Core/src/RequireHttpsAttribute.cs b/src/Mvc/Mvc.Core/src/RequireHttpsAttribute.cs index f8f9c19c01..da616af153 100644 --- a/src/Mvc/Mvc.Core/src/RequireHttpsAttribute.cs +++ b/src/Mvc/Mvc.Core/src/RequireHttpsAttribute.cs @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc { // only redirect for GET requests, otherwise the browser might not propagate the verb and request // body correctly. - if (!string.Equals(filterContext.HttpContext.Request.Method, "GET", StringComparison.OrdinalIgnoreCase)) + if (!HttpMethods.IsGet(filterContext.HttpContext.Request.Method)) { filterContext.Result = new StatusCodeResult(StatusCodes.Status403Forbidden); } diff --git a/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs b/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs index 8f3b4dd74b..52b81b9145 100644 --- a/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs +++ b/src/Mvc/Mvc.Core/src/Routing/ActionEndpointFactory.cs @@ -132,7 +132,14 @@ namespace Microsoft.AspNetCore.Mvc.Routing var updatedRoutePattern = _routePatternTransformer.SubstituteRequiredValues(resolvedRoutePattern, resolvedRouteValues); if (updatedRoutePattern == null) { - throw new InvalidOperationException("Failed to update route pattern with required values."); + // This kind of thing can happen when a route pattern uses a *reserved* route value such as `action`. + // See: https://github.com/dotnet/aspnetcore/issues/14789 + var formattedRouteKeys = string.Join(", ", resolvedRouteValues.Keys.Select(k => $"'{k}'")); + throw new InvalidOperationException( + $"Failed to update the route pattern '{resolvedRoutePattern.RawText}' with required route values. " + + $"This can occur when the route pattern contains parameters with reserved names such as: {formattedRouteKeys} " + + $"and also uses route constraints such as '{{action:int}}'. " + + $"To fix this error, choose a different parmaeter name."); } var builder = new RouteEndpointBuilder(_requestDelegate, updatedRoutePattern, action.AttributeRouteInfo.Order) @@ -292,7 +299,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing } private void AddActionDataToBuilder( - EndpointBuilder builder, + EndpointBuilder builder, HashSet routeNames, ActionDescriptor action, string routeName, @@ -325,9 +332,9 @@ namespace Microsoft.AspNetCore.Mvc.Routing // However, Endpoint Routing requires Endpoint Names to be unique. // // We can use the route name as the endpoint name if it's not set. Note that there's no - // attribute for this today so it's unlikley. Using endpoint name on a - if (routeName != null && - !suppressLinkGeneration && + // attribute for this today so it's unlikley. Using endpoint name on a + if (routeName != null && + !suppressLinkGeneration && routeNames.Add(routeName) && builder.Metadata.OfType().LastOrDefault()?.EndpointName == null) { diff --git a/src/Mvc/Mvc.Core/src/Routing/IRouteValueProvider.cs b/src/Mvc/Mvc.Core/src/Routing/IRouteValueProvider.cs index 6bd09db26b..e40059bbbd 100644 --- a/src/Mvc/Mvc.Core/src/Routing/IRouteValueProvider.cs +++ b/src/Mvc/Mvc.Core/src/Routing/IRouteValueProvider.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing /// /// /// - /// For an action like MyApp.Controllers.HomeController.Index(), in order to be selected, the + /// For an action like MyApp.Controllers.HomeController.Index(), in order to be selected, the /// must contain the values /// { /// "action": "Index", @@ -39,11 +39,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing /// ) or are considered 'outside' of areas by having the value null. /// /// - /// Consider an application with two controllers, each with an Index action method: - /// - MyApp.Controllers.HomeController.Index() - /// - MyApp.Areas.Blog.Controllers.HomeController.Index() - /// where MyApp.Areas.Blog.Controllers.HomeController has an area attribute - /// [Area("Blog")]. + /// Consider an application with two controllers, each with an Index action method: + /// - MyApp.Controllers.HomeController.Index() + /// - MyApp.Areas.Blog.Controllers.HomeController.Index() + /// where MyApp.Areas.Blog.Controllers.HomeController has an area attribute + /// [Area("Blog")]. /// /// For like: /// { @@ -51,8 +51,8 @@ namespace Microsoft.AspNetCore.Mvc.Routing /// "controller": "Home" /// } /// - /// MyApp.Controllers.HomeController.Index() will be selected. - /// MyApp.Area.Blog.Controllers.HomeController.Index() is not considered eligible because the + /// MyApp.Controllers.HomeController.Index() will be selected. + /// MyApp.Area.Blog.Controllers.HomeController.Index() is not considered eligible because the /// does not contain the value 'Blog' for 'area'. /// /// For like: @@ -62,9 +62,9 @@ namespace Microsoft.AspNetCore.Mvc.Routing /// "controller": "Home" /// } /// - /// MyApp.Area.Blog.Controllers.HomeController.Index() will be selected. - /// MyApp.Controllers.HomeController.Index() is not considered eligible because the route values - /// contain a value for 'area'. MyApp.Controllers.HomeController.Index() cannot match any value + /// MyApp.Area.Blog.Controllers.HomeController.Index() will be selected. + /// MyApp.Controllers.HomeController.Index() is not considered eligible because the route values + /// contain a value for 'area'. MyApp.Controllers.HomeController.Index() cannot match any value /// for 'area' other than null. /// /// diff --git a/src/Mvc/Mvc.Core/src/Routing/UrlHelperFactory.cs b/src/Mvc/Mvc.Core/src/Routing/UrlHelperFactory.cs index dfe16c2421..5fffa77974 100644 --- a/src/Mvc/Mvc.Core/src/Routing/UrlHelperFactory.cs +++ b/src/Mvc/Mvc.Core/src/Routing/UrlHelperFactory.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing { if (context == null) { - throw new ArgumentNullException(Resources.ArgumentCannotBeNullOrEmpty, (nameof(context))); + throw new ArgumentNullException(nameof(context)); } var httpContext = context.HttpContext; @@ -69,4 +69,4 @@ namespace Microsoft.AspNetCore.Mvc.Routing return urlHelper; } } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.Core/src/VirtualFileResult.cs b/src/Mvc/Mvc.Core/src/VirtualFileResult.cs index af075b5a09..e44b0623ff 100644 --- a/src/Mvc/Mvc.Core/src/VirtualFileResult.cs +++ b/src/Mvc/Mvc.Core/src/VirtualFileResult.cs @@ -27,10 +27,6 @@ namespace Microsoft.AspNetCore.Mvc public VirtualFileResult(string fileName, string contentType) : this(fileName, MediaTypeHeaderValue.Parse(contentType)) { - if (fileName == null) - { - throw new ArgumentNullException(nameof(fileName)); - } } /// diff --git a/src/Mvc/Mvc.Core/test/Authorization/AuthorizeFilterTest.cs b/src/Mvc/Mvc.Core/test/Authorization/AuthorizeFilterTest.cs index e5c390395b..15d2341e12 100644 --- a/src/Mvc/Mvc.Core/test/Authorization/AuthorizeFilterTest.cs +++ b/src/Mvc/Mvc.Core/test/Authorization/AuthorizeFilterTest.cs @@ -317,11 +317,11 @@ namespace Microsoft.AspNetCore.Mvc.Authorization public async Task AuthorizationFilterCombinesMultipleFilters() { // Arrange - var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => true).Build()); + var authorizeFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => false).Build()); var authorizationContext = GetAuthorizationContext(anonymous: false); // Effective policy should fail, if both are combined authorizationContext.Filters.Add(authorizeFilter); - var secondFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => false).Build()); + var secondFilter = new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAssertion(a => true).Build()); authorizationContext.Filters.Add(secondFilter); // Act diff --git a/src/Mvc/Mvc.Core/test/DependencyInjection/ApiBehaviorOptionsSetupTest.cs b/src/Mvc/Mvc.Core/test/DependencyInjection/ApiBehaviorOptionsSetupTest.cs index ebca639ee9..c6700283eb 100644 --- a/src/Mvc/Mvc.Core/test/DependencyInjection/ApiBehaviorOptionsSetupTest.cs +++ b/src/Mvc/Mvc.Core/test/DependencyInjection/ApiBehaviorOptionsSetupTest.cs @@ -7,6 +7,8 @@ using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Moq; using Xunit; namespace Microsoft.Extensions.DependencyInjection @@ -70,6 +72,29 @@ namespace Microsoft.Extensions.DependencyInjection Assert.Equal(link, problemDetails.Type); } + [Fact] + public void ProblemDetailsInvalidModelStateResponse_UsesProblemDetailsFactory() + { + // Arrange + var actionContext = GetActionContext(); + var factory = Mock.Of(m => m.CreateValidationProblemDetails(It.IsAny(), It.IsAny(), null, null, null, null, null) == new ValidationProblemDetails + { + Status = 422, + }); + + // Act + var result = ApiBehaviorOptionsSetup.ProblemDetailsInvalidModelStateResponse(factory, actionContext); + + // Assert + var objectResult = Assert.IsType(result); + Assert.Equal(422, objectResult.StatusCode); + Assert.Equal(new[] { "application/problem+json", "application/problem+xml" }, objectResult.ContentTypes.OrderBy(c => c)); + + var problemDetails = Assert.IsType(objectResult.Value); + Assert.Equal(422, problemDetails.Status); + Assert.Equal("One or more validation errors occurred.", problemDetails.Title); + } + [Fact] public void ProblemDetailsInvalidModelStateResponse_SetsTraceId() { diff --git a/src/Mvc/Mvc.Core/test/Infrastructure/AsyncEnumerableReaderTest.cs b/src/Mvc/Mvc.Core/test/Infrastructure/AsyncEnumerableReaderTest.cs index 27baf232c9..4a3a861ed4 100644 --- a/src/Mvc/Mvc.Core/test/Infrastructure/AsyncEnumerableReaderTest.cs +++ b/src/Mvc/Mvc.Core/test/Infrastructure/AsyncEnumerableReaderTest.cs @@ -5,46 +5,173 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Options; using Xunit; namespace Microsoft.AspNetCore.Mvc.Infrastructure { public class AsyncEnumerableReaderTest { - [Fact] - public async Task ReadAsync_ReadsIAsyncEnumerable() + [Theory] + [InlineData(typeof(Range))] + [InlineData(typeof(IEnumerable))] + [InlineData(typeof(List))] + public void TryGetReader_ReturnsFalse_IfTypeIsNotIAsyncEnumerable(Type type) { // Arrange var options = new MvcOptions(); - var reader = new AsyncEnumerableReader(options); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable = TestEnumerable(); // Act - var result = await reader.ReadAsync(TestEnumerable()); + var result = readerFactory.TryGetReader(type, out var reader); // Assert - var collection = Assert.IsAssignableFrom>(result); + Assert.False(result); + } + + [Fact] + public async Task TryGetReader_ReturnsReaderForIAsyncEnumerable() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable = TestEnumerable(); + + // Act + var result = readerFactory.TryGetReader(asyncEnumerable.GetType(), out var reader); + + // Assert + Assert.True(result); + var readCollection = await reader(asyncEnumerable); + var collection = Assert.IsAssignableFrom>(readCollection); Assert.Equal(new[] { "0", "1", "2", }, collection); } [Fact] - public async Task ReadAsync_ReadsIAsyncEnumerable_ImplementingMultipleAsyncEnumerableInterfaces() + public async Task TryGetReader_ReturnsReaderForIAsyncEnumerableOfValueType() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable = PrimitiveEnumerable(); + + // Act + var result = readerFactory.TryGetReader(asyncEnumerable.GetType(), out var reader); + + // Assert + Assert.True(result); + var readCollection = await reader(asyncEnumerable); + var collection = Assert.IsAssignableFrom>(readCollection); + Assert.Equal(new[] { 0, 1, 2, }, collection); + } + + [Fact] + public void TryGetReader_ReturnsCachedDelegate() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable1 = TestEnumerable(); + var asyncEnumerable2 = TestEnumerable(); + + // Act + Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader1)); + Assert.True(readerFactory.TryGetReader(asyncEnumerable2.GetType(), out var reader2)); + + // Assert + Assert.Same(reader1, reader2); + } + + [Fact] + public void TryGetReader_ReturnsCachedDelegate_WhenTypeImplementsMultipleIAsyncEnumerableContracts() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable1 = new MultiAsyncEnumerable(); + var asyncEnumerable2 = new MultiAsyncEnumerable(); + + // Act + Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader1)); + Assert.True(readerFactory.TryGetReader(asyncEnumerable2.GetType(), out var reader2)); + + // Assert + Assert.Same(reader1, reader2); + } + + [Fact] + public async Task CachedDelegate_CanReadEnumerableInstanceMultipleTimes() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable1 = TestEnumerable(); + var asyncEnumerable2 = TestEnumerable(); + var expected = new[] { "0", "1", "2" }; + + // Act + Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader)); + + // Assert + Assert.Equal(expected, await reader(asyncEnumerable1)); + Assert.Equal(expected, await reader(asyncEnumerable2)); + } + + [Fact] + public async Task CachedDelegate_CanReadEnumerableInstanceMultipleTimes_ThatProduceDifferentResults() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable1 = TestEnumerable(); + var asyncEnumerable2 = TestEnumerable(4); + + // Act + Assert.True(readerFactory.TryGetReader(asyncEnumerable1.GetType(), out var reader)); + + // Assert + Assert.Equal(new[] { "0", "1", "2" }, await reader(asyncEnumerable1)); + Assert.Equal(new[] { "0", "1", "2", "3" }, await reader(asyncEnumerable2)); + } + + [Fact] + public void TryGetReader_ReturnsDifferentInstancesForDifferentEnumerables() + { + // Arrange + var options = new MvcOptions(); + var readerFactory = new AsyncEnumerableReader(options); + var enumerable1 = TestEnumerable(); + var enumerable2 = TestEnumerable2(); + + // Act + Assert.True(readerFactory.TryGetReader(enumerable1.GetType(), out var reader1)); + Assert.True(readerFactory.TryGetReader(enumerable2.GetType(), out var reader2)); + + // Assert + Assert.NotSame(reader1, reader2); + } + + [Fact] + public async Task Reader_ReadsIAsyncEnumerable_ImplementingMultipleAsyncEnumerableInterfaces() { // This test ensures the reader does not fail if you have a type that implements IAsyncEnumerable for multiple Ts // Arrange var options = new MvcOptions(); - var reader = new AsyncEnumerableReader(options); + var readerFactory = new AsyncEnumerableReader(options); + var asyncEnumerable = new MultiAsyncEnumerable(); // Act - var result = await reader.ReadAsync(new MultiAsyncEnumerable()); + var result = readerFactory.TryGetReader(asyncEnumerable.GetType(), out var reader); // Assert - var collection = Assert.IsAssignableFrom>(result); + Assert.True(result); + var readCollection = await reader(asyncEnumerable); + var collection = Assert.IsAssignableFrom>(readCollection); Assert.Equal(new[] { "0", "1", "2", }, collection); } - [Fact] - public async Task ReadAsync_ThrowsIfBufferimitIsReached() + [Fact] + public async Task Reader_ThrowsIfBufferLimitIsReached() { // Arrange var enumerable = TestEnumerable(11); @@ -52,10 +179,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure "This limit is in place to prevent infinite streams of 'IAsyncEnumerable<>' from continuing indefinitely. If this is not a programming mistake, " + $"consider ways to reduce the collection size, or consider manually converting '{enumerable.GetType()}' into a list rather than increasing the limit."; var options = new MvcOptions { MaxIAsyncEnumerableBufferLimit = 10 }; - var reader = new AsyncEnumerableReader(options); + var readerFactory = new AsyncEnumerableReader(options); // Act - var ex = await Assert.ThrowsAsync(() => reader.ReadAsync(enumerable)); + Assert.True(readerFactory.TryGetReader(enumerable.GetType(), out var reader)); + var ex = await Assert.ThrowsAsync(() => reader(enumerable)); // Assert Assert.Equal(expected, ex.Message); @@ -70,6 +198,22 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure } } + public static async IAsyncEnumerable TestEnumerable2() + { + await Task.Yield(); + yield return "Hello"; + yield return "world"; + } + + public static async IAsyncEnumerable PrimitiveEnumerable(int count = 3) + { + await Task.Yield(); + for (var i = 0; i < count; i++) + { + yield return i; + } + } + public class MultiAsyncEnumerable : IAsyncEnumerable, IAsyncEnumerable { public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) diff --git a/src/Mvc/Mvc.Core/test/Infrastructure/JsonResultExecutorTestBase.cs b/src/Mvc/Mvc.Core/test/Infrastructure/JsonResultExecutorTestBase.cs index 7b74959cdc..8d0fa3ef84 100644 --- a/src/Mvc/Mvc.Core/test/Infrastructure/JsonResultExecutorTestBase.cs +++ b/src/Mvc/Mvc.Core/test/Infrastructure/JsonResultExecutorTestBase.cs @@ -311,6 +311,24 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure Assert.StartsWith("Property 'JsonResult.SerializerSettings' must be an instance of type", ex.Message); } + [Fact] + public async Task ExecuteAsync_WithNullValue() + { + // Arrange + var expected = Encoding.UTF8.GetBytes("null"); + + var context = GetActionContext(); + var result = new JsonResult(value: null); + var executor = CreateExecutor(); + + // Act + await executor.ExecuteAsync(context, result); + + // Assert + var written = GetWrittenBytes(context.HttpContext); + Assert.Equal(expected, written); + } + [Fact] public async Task ExecuteAsync_SerializesAsyncEnumerables() { @@ -329,6 +347,24 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure Assert.Equal(expected, written); } + [Fact] + public async Task ExecuteAsync_SerializesAsyncEnumerablesOfPrimtives() + { + // Arrange + var expected = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new[] { 1, 2 })); + + var context = GetActionContext(); + var result = new JsonResult(TestAsyncPrimitiveEnumerable()); + var executor = CreateExecutor(); + + // Act + await executor.ExecuteAsync(context, result); + + // Assert + var written = GetWrittenBytes(context.HttpContext); + Assert.Equal(expected, written); + } + protected IActionResultExecutor CreateExecutor() => CreateExecutor(NullLoggerFactory.Instance); protected abstract IActionResultExecutor CreateExecutor(ILoggerFactory loggerFactory); @@ -380,5 +416,12 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure yield return "Hello"; yield return "world"; } + + private async IAsyncEnumerable TestAsyncPrimitiveEnumerable() + { + await Task.Yield(); + yield return 1; + yield return 2; + } } } diff --git a/src/Mvc/Mvc.Core/test/Infrastructure/ObjectResultExecutorTest.cs b/src/Mvc/Mvc.Core/test/Infrastructure/ObjectResultExecutorTest.cs index 8ab2d76678..395362f8bf 100644 --- a/src/Mvc/Mvc.Core/test/Infrastructure/ObjectResultExecutorTest.cs +++ b/src/Mvc/Mvc.Core/test/Infrastructure/ObjectResultExecutorTest.cs @@ -361,6 +361,28 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure MediaTypeAssert.Equal(expectedContentType, responseContentType); } + [Fact] + public async Task ObjectResult_NullValue() + { + // Arrange + var executor = CreateExecutor(); + var result = new ObjectResult(value: null); + var formatter = new TestJsonOutputFormatter(); + result.Formatters.Add(formatter); + + var actionContext = new ActionContext() + { + HttpContext = GetHttpContext(), + }; + + // Act + await executor.ExecuteAsync(actionContext, result); + + // Assert + var formatterContext = formatter.LastOutputFormatterContext; + Assert.Null(formatterContext.Object); + } + [Fact] public async Task ObjectResult_ReadsAsyncEnumerables() { diff --git a/src/Mvc/Mvc.Core/test/ObjectResultTests.cs b/src/Mvc/Mvc.Core/test/ObjectResultTests.cs index 5f210f2921..187e1ede7c 100644 --- a/src/Mvc/Mvc.Core/test/ObjectResultTests.cs +++ b/src/Mvc/Mvc.Core/test/ObjectResultTests.cs @@ -94,6 +94,68 @@ namespace Microsoft.AspNetCore.Mvc Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value); } + [Fact] + public async Task ObjectResult_ExecuteResultAsync_GetsStatusCodeFromProblemDetails() + { + // Arrange + var details = new ProblemDetails { Status = StatusCodes.Status413RequestEntityTooLarge, }; + + var result = new ObjectResult(details) + { + Formatters = new FormatterCollection() + { + new NoOpOutputFormatter(), + }, + }; + + var actionContext = new ActionContext() + { + HttpContext = new DefaultHttpContext() + { + RequestServices = CreateServices(), + } + }; + + // Act + await result.ExecuteResultAsync(actionContext); + + // Assert + Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, details.Status.Value); + Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, result.StatusCode.Value); + Assert.Equal(StatusCodes.Status413RequestEntityTooLarge, actionContext.HttpContext.Response.StatusCode); + } + + [Fact] + public async Task ObjectResult_ExecuteResultAsync_ResultAndProblemDetailsHaveStatusCodes() + { + // Arrange + var details = new ProblemDetails { Status = StatusCodes.Status422UnprocessableEntity, }; + + var result = new BadRequestObjectResult(details) + { + Formatters = new FormatterCollection() + { + new NoOpOutputFormatter(), + }, + }; + + var actionContext = new ActionContext() + { + HttpContext = new DefaultHttpContext() + { + RequestServices = CreateServices(), + } + }; + + // Act + await result.ExecuteResultAsync(actionContext); + + // Assert + Assert.Equal(StatusCodes.Status422UnprocessableEntity, details.Status.Value); + Assert.Equal(StatusCodes.Status400BadRequest, result.StatusCode.Value); + Assert.Equal(StatusCodes.Status400BadRequest, actionContext.HttpContext.Response.StatusCode); + } + private static IServiceProvider CreateServices() { var services = new ServiceCollection(); diff --git a/src/Mvc/Mvc.Core/test/Routing/ActionEndpointFactoryTest.cs b/src/Mvc/Mvc.Core/test/Routing/ActionEndpointFactoryTest.cs index 0eb69069bf..00f89b09d2 100644 --- a/src/Mvc/Mvc.Core/test/Routing/ActionEndpointFactoryTest.cs +++ b/src/Mvc/Mvc.Core/test/Routing/ActionEndpointFactoryTest.cs @@ -208,6 +208,22 @@ namespace Microsoft.AspNetCore.Mvc.Routing Assert.Empty(endpoints); } + [Fact] + public void AddEndpoints_AttributeRouted_ContainsParameterUsingReservedNameWithConstraint_ExceptionThrown() + { + // Arrange + var values = new { controller = "TestController", action = "TestAction", page = (string)null }; + var action = CreateActionDescriptor(values, "Products/{action:int}"); + + // Act & Assert + var exception = Assert.Throws(() => CreateAttributeRoutedEndpoint(action)); + Assert.Equal( + "Failed to update the route pattern 'Products/{action:int}' with required route values. " + + "This can occur when the route pattern contains parameters with reserved names such as: 'controller', 'action', 'page' and also uses route constraints such as '{action:int}'. " + + "To fix this error, choose a different parmaeter name.", + exception.Message); + } + [Fact] public void AddEndpoints_AttributeRouted_ContainsParameterWithNullRequiredRouteValue_EndpointCreated() { diff --git a/src/Mvc/Mvc.Cors/ref/Microsoft.AspNetCore.Mvc.Cors.netcoreapp.cs b/src/Mvc/Mvc.Cors/ref/Microsoft.AspNetCore.Mvc.Cors.netcoreapp.cs index 5a433b69a3..ad0a715638 100644 --- a/src/Mvc/Mvc.Cors/ref/Microsoft.AspNetCore.Mvc.Cors.netcoreapp.cs +++ b/src/Mvc/Mvc.Cors/ref/Microsoft.AspNetCore.Mvc.Cors.netcoreapp.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Mvc.Cors public CorsAuthorizationFilter(Microsoft.AspNetCore.Cors.Infrastructure.ICorsService corsService, Microsoft.AspNetCore.Cors.Infrastructure.ICorsPolicyProvider policyProvider) { } public CorsAuthorizationFilter(Microsoft.AspNetCore.Cors.Infrastructure.ICorsService corsService, Microsoft.AspNetCore.Cors.Infrastructure.ICorsPolicyProvider policyProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public int Order { get { throw null; } } - public string PolicyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PolicyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task OnAuthorizationAsync(Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext context) { throw null; } } diff --git a/src/Mvc/Mvc.Cors/src/CorsAuthorizationFilter.cs b/src/Mvc/Mvc.Cors/src/CorsAuthorizationFilter.cs index f40003abd6..2ad0f3ebb4 100644 --- a/src/Mvc/Mvc.Cors/src/CorsAuthorizationFilter.cs +++ b/src/Mvc/Mvc.Cors/src/CorsAuthorizationFilter.cs @@ -103,11 +103,8 @@ namespace Microsoft.AspNetCore.Mvc.Cors var accessControlRequestMethod = httpContext.Request.Headers[CorsConstants.AccessControlRequestMethod]; - if (string.Equals( - request.Method, - CorsConstants.PreflightHttpMethod, - StringComparison.OrdinalIgnoreCase) && - !StringValues.IsNullOrEmpty(accessControlRequestMethod)) + if (HttpMethods.IsOptions(request.Method) + && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { // If this was a preflight, there is no need to run anything else. context.Result = new StatusCodeResult(StatusCodes.Status204NoContent); diff --git a/src/Mvc/Mvc.Cors/src/CorsHttpMethodActionConstraint.cs b/src/Mvc/Mvc.Cors/src/CorsHttpMethodActionConstraint.cs index cab2f0c676..4fb9a22f68 100644 --- a/src/Mvc/Mvc.Cors/src/CorsHttpMethodActionConstraint.cs +++ b/src/Mvc/Mvc.Cors/src/CorsHttpMethodActionConstraint.cs @@ -12,7 +12,6 @@ namespace Microsoft.AspNetCore.Mvc.Cors { private readonly string OriginHeader = "Origin"; private readonly string AccessControlRequestMethod = "Access-Control-Request-Method"; - private readonly string PreflightHttpMethod = "OPTIONS"; public CorsHttpMethodActionConstraint(HttpMethodActionConstraint constraint) : base(constraint.HttpMethods) @@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.Cors var request = context.RouteContext.HttpContext.Request; // Perf: Check http method before accessing the Headers collection. - if (string.Equals(request.Method, PreflightHttpMethod, StringComparison.OrdinalIgnoreCase) && + if (Http.HttpMethods.IsOptions(request.Method) && request.Headers.ContainsKey(OriginHeader) && request.Headers.TryGetValue(AccessControlRequestMethod, out var accessControlRequestMethod) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) diff --git a/src/Mvc/Mvc.DataAnnotations/ref/Microsoft.AspNetCore.Mvc.DataAnnotations.netcoreapp.cs b/src/Mvc/Mvc.DataAnnotations/ref/Microsoft.AspNetCore.Mvc.DataAnnotations.netcoreapp.cs index 900e7246b2..7a56e2fb0c 100644 --- a/src/Mvc/Mvc.DataAnnotations/ref/Microsoft.AspNetCore.Mvc.DataAnnotations.netcoreapp.cs +++ b/src/Mvc/Mvc.DataAnnotations/ref/Microsoft.AspNetCore.Mvc.DataAnnotations.netcoreapp.cs @@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Mvc public sealed partial class HiddenInputAttribute : System.Attribute { public HiddenInputAttribute() { } - public bool DisplayValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool DisplayValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Mvc.DataAnnotations @@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations public abstract partial class ValidationAttributeAdapter : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IClientModelValidator where TAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public ValidationAttributeAdapter(TAttribute attribute, Microsoft.Extensions.Localization.IStringLocalizer stringLocalizer) { } - public TAttribute Attribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public TAttribute Attribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract void AddValidation(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientModelValidationContext context); protected virtual string GetErrorMessage(Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata modelMetadata, params object[] arguments) { throw null; } protected static bool MergeAttribute(System.Collections.Generic.IDictionary attributes, string key, string value) { throw null; } diff --git a/src/Mvc/Mvc.DataAnnotations/src/DataAnnotationsMetadataProvider.cs b/src/Mvc/Mvc.DataAnnotations/src/DataAnnotationsMetadataProvider.cs index a5c2b3f4c9..124391b4a9 100644 --- a/src/Mvc/Mvc.DataAnnotations/src/DataAnnotationsMetadataProvider.cs +++ b/src/Mvc/Mvc.DataAnnotations/src/DataAnnotationsMetadataProvider.cs @@ -369,9 +369,9 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations var property = context.Key.PropertyInfo; if (property is null) { - // PropertyInfo was unavailable on ModelIdentity prior to 3.1. + // PropertyInfo was unavailable on ModelIdentity prior to 3.1. // Making a cogent argument about the nullability of the property requires inspecting the declared type, - // since looking at the runtime type may result in false positives: https://github.com/aspnet/AspNetCore/issues/14812 + // since looking at the runtime type may result in false positives: https://github.com/dotnet/aspnetcore/issues/14812 // The only way we could arrive here is if the ModelMetadata was constructed using the non-default provider. // We'll cursorily examine the attributes on the property, but not the ContainerType to make a decision about it's nullability. @@ -498,7 +498,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations // See: https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-reference-types.md#annotations if (nullableAttribute.GetType().GetField(NullableFlagsFieldName) is FieldInfo field && field.GetValue(nullableAttribute) is byte[] flags && - flags.Length >= 0 && + flags.Length > 0 && flags[0] == 1) // First element is the property/parameter type. { isNullable = true; diff --git a/src/Mvc/Mvc.DataAnnotations/src/ValidationAttributeAdapterProvider.cs b/src/Mvc/Mvc.DataAnnotations/src/ValidationAttributeAdapterProvider.cs index 7ec543d39d..a32a28a032 100644 --- a/src/Mvc/Mvc.DataAnnotations/src/ValidationAttributeAdapterProvider.cs +++ b/src/Mvc/Mvc.DataAnnotations/src/ValidationAttributeAdapterProvider.cs @@ -29,51 +29,51 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations var type = attribute.GetType(); - if (type == typeof(RegularExpressionAttribute)) + if (typeof(RegularExpressionAttribute).IsAssignableFrom(type)) { adapter = new RegularExpressionAttributeAdapter((RegularExpressionAttribute)attribute, stringLocalizer); } - else if (type == typeof(MaxLengthAttribute)) + else if (typeof(MaxLengthAttribute).IsAssignableFrom(type)) { adapter = new MaxLengthAttributeAdapter((MaxLengthAttribute)attribute, stringLocalizer); } - else if (type == typeof(RequiredAttribute)) + else if (typeof(RequiredAttribute).IsAssignableFrom(type)) { adapter = new RequiredAttributeAdapter((RequiredAttribute)attribute, stringLocalizer); } - else if (type == typeof(CompareAttribute)) + else if (typeof(CompareAttribute).IsAssignableFrom(type)) { adapter = new CompareAttributeAdapter((CompareAttribute)attribute, stringLocalizer); } - else if (type == typeof(MinLengthAttribute)) + else if (typeof(MinLengthAttribute).IsAssignableFrom(type)) { adapter = new MinLengthAttributeAdapter((MinLengthAttribute)attribute, stringLocalizer); } - else if (type == typeof(CreditCardAttribute)) + else if (typeof(CreditCardAttribute).IsAssignableFrom(type)) { adapter = new DataTypeAttributeAdapter((DataTypeAttribute)attribute, "data-val-creditcard", stringLocalizer); } - else if (type == typeof(StringLengthAttribute)) + else if (typeof(StringLengthAttribute).IsAssignableFrom(type)) { adapter = new StringLengthAttributeAdapter((StringLengthAttribute)attribute, stringLocalizer); } - else if (type == typeof(RangeAttribute)) + else if (typeof(RangeAttribute).IsAssignableFrom(type)) { adapter = new RangeAttributeAdapter((RangeAttribute)attribute, stringLocalizer); } - else if (type == typeof(EmailAddressAttribute)) + else if (typeof(EmailAddressAttribute).IsAssignableFrom(type)) { adapter = new DataTypeAttributeAdapter((DataTypeAttribute)attribute, "data-val-email", stringLocalizer); } - else if (type == typeof(PhoneAttribute)) + else if (typeof(PhoneAttribute).IsAssignableFrom(type)) { adapter = new DataTypeAttributeAdapter((DataTypeAttribute)attribute, "data-val-phone", stringLocalizer); } - else if (type == typeof(UrlAttribute)) + else if (typeof(UrlAttribute).IsAssignableFrom(type)) { adapter = new DataTypeAttributeAdapter((DataTypeAttribute)attribute, "data-val-url", stringLocalizer); } - else if (type == typeof(FileExtensionsAttribute)) + else if (typeof(FileExtensionsAttribute).IsAssignableFrom(type)) { adapter = new FileExtensionsAttributeAdapter((FileExtensionsAttribute)attribute, stringLocalizer); } diff --git a/src/Mvc/Mvc.DataAnnotations/test/DataAnnotationsMetadataProviderTest.cs b/src/Mvc/Mvc.DataAnnotations/test/DataAnnotationsMetadataProviderTest.cs index 9760421c9a..fc05b7cb12 100644 --- a/src/Mvc/Mvc.DataAnnotations/test/DataAnnotationsMetadataProviderTest.cs +++ b/src/Mvc/Mvc.DataAnnotations/test/DataAnnotationsMetadataProviderTest.cs @@ -1310,7 +1310,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations [Fact] public void CreateValidationMetadata_InfersRequiredAttribute_BaseTypeIsNullable_PropertyIsNotNull() { - // Tests the scenario listed in https://github.com/aspnet/AspNetCore/issues/14812 + // Tests the scenario listed in https://github.com/dotnet/aspnetcore/issues/14812 // Arrange var provider = CreateProvider(); diff --git a/src/Mvc/Mvc.DataAnnotations/test/ValidationAttributeAdapterProviderTest.cs b/src/Mvc/Mvc.DataAnnotations/test/ValidationAttributeAdapterProviderTest.cs index ef6027c5a1..51d0c6f4a7 100644 --- a/src/Mvc/Mvc.DataAnnotations/test/ValidationAttributeAdapterProviderTest.cs +++ b/src/Mvc/Mvc.DataAnnotations/test/ValidationAttributeAdapterProviderTest.cs @@ -41,6 +41,10 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations { new RequiredAttribute(), typeof(RequiredAttributeAdapter) + }, + { + new CustomRegularExpressionAttribute("abc"), + typeof(RegularExpressionAttributeAdapter) } }; } @@ -85,5 +89,13 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations var dataTypeAdapter = Assert.IsType(adapter); Assert.Equal(expectedRuleName, dataTypeAdapter.RuleName); } + + class CustomRegularExpressionAttribute : RegularExpressionAttribute + { + public CustomRegularExpressionAttribute(string pattern) : base(pattern) + { + ErrorMessage = "Not valid."; + } + } } } diff --git a/src/Mvc/Mvc.Formatters.Xml/ref/Microsoft.AspNetCore.Mvc.Formatters.Xml.netcoreapp.cs b/src/Mvc/Mvc.Formatters.Xml/ref/Microsoft.AspNetCore.Mvc.Formatters.Xml.netcoreapp.cs index fa9ffb071d..14babc4f8f 100644 --- a/src/Mvc/Mvc.Formatters.Xml/ref/Microsoft.AspNetCore.Mvc.Formatters.Xml.netcoreapp.cs +++ b/src/Mvc/Mvc.Formatters.Xml/ref/Microsoft.AspNetCore.Mvc.Formatters.Xml.netcoreapp.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public virtual Microsoft.AspNetCore.Mvc.Formatters.InputFormatterExceptionPolicy ExceptionPolicy { get { throw null; } } public int MaxDepth { get { throw null; } set { } } public System.Runtime.Serialization.DataContractSerializerSettings SerializerSettings { get { throw null; } set { } } - public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Xml.XmlDictionaryReaderQuotas XmlDictionaryReaderQuotas { get { throw null; } } protected override bool CanReadType(System.Type type) { throw null; } protected virtual System.Runtime.Serialization.DataContractSerializer CreateSerializer(System.Type type) { throw null; } @@ -26,8 +26,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public XmlDataContractSerializerOutputFormatter(System.Xml.XmlWriterSettings writerSettings) { } public XmlDataContractSerializerOutputFormatter(System.Xml.XmlWriterSettings writerSettings, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public System.Runtime.Serialization.DataContractSerializerSettings SerializerSettings { get { throw null; } set { } } - public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Xml.XmlWriterSettings WriterSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Xml.XmlWriterSettings WriterSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override bool CanWriteType(System.Type type) { throw null; } protected virtual System.Runtime.Serialization.DataContractSerializer CreateSerializer(System.Type type) { throw null; } public virtual System.Xml.XmlWriter CreateXmlWriter(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context, System.IO.TextWriter writer, System.Xml.XmlWriterSettings xmlWriterSettings) { throw null; } @@ -42,11 +42,12 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public XmlSerializerInputFormatter(Microsoft.AspNetCore.Mvc.MvcOptions options) { } public virtual Microsoft.AspNetCore.Mvc.Formatters.InputFormatterExceptionPolicy ExceptionPolicy { get { throw null; } } public int MaxDepth { get { throw null; } set { } } - public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Xml.XmlDictionaryReaderQuotas XmlDictionaryReaderQuotas { get { throw null; } } protected override bool CanReadType(System.Type type) { throw null; } protected virtual System.Xml.Serialization.XmlSerializer CreateSerializer(System.Type type) { throw null; } protected virtual System.Xml.XmlReader CreateXmlReader(System.IO.Stream readStream, System.Text.Encoding encoding) { throw null; } + protected virtual System.Xml.XmlReader CreateXmlReader(System.IO.Stream readStream, System.Text.Encoding encoding, System.Type type) { throw null; } protected virtual System.Xml.Serialization.XmlSerializer GetCachedSerializer(System.Type type) { throw null; } protected virtual System.Type GetSerializableType(System.Type declaredType) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -58,8 +59,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public XmlSerializerOutputFormatter(Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public XmlSerializerOutputFormatter(System.Xml.XmlWriterSettings writerSettings) { } public XmlSerializerOutputFormatter(System.Xml.XmlWriterSettings writerSettings, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } - public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Xml.XmlWriterSettings WriterSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList WrapperProviderFactories { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Xml.XmlWriterSettings WriterSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override bool CanWriteType(System.Type type) { throw null; } protected virtual System.Xml.Serialization.XmlSerializer CreateSerializer(System.Type type) { throw null; } public virtual System.Xml.XmlWriter CreateXmlWriter(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context, System.IO.TextWriter writer, System.Xml.XmlWriterSettings xmlWriterSettings) { throw null; } @@ -93,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml public partial class EnumerableWrapperProvider : Microsoft.AspNetCore.Mvc.Formatters.Xml.IWrapperProvider { public EnumerableWrapperProvider(System.Type sourceEnumerableOfT, Microsoft.AspNetCore.Mvc.Formatters.Xml.IWrapperProvider elementWrapperProvider) { } - public System.Type WrappingType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type WrappingType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public object Wrap(object original) { throw null; } } public partial class EnumerableWrapperProviderFactory : Microsoft.AspNetCore.Mvc.Formatters.Xml.IWrapperProviderFactory @@ -137,7 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml { public SerializableErrorWrapper() { } public SerializableErrorWrapper(Microsoft.AspNetCore.Mvc.SerializableError error) { } - public Microsoft.AspNetCore.Mvc.SerializableError SerializableError { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.SerializableError SerializableError { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Xml.Schema.XmlSchema GetSchema() { throw null; } public void ReadXml(System.Xml.XmlReader reader) { } public object Unwrap(System.Type declaredType) { throw null; } @@ -166,8 +167,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters.Xml public partial class WrapperProviderContext { public WrapperProviderContext(System.Type declaredType, bool isSerialization) { } - public System.Type DeclaredType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsSerialization { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type DeclaredType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsSerialization { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class WrapperProviderFactoriesExtensions { diff --git a/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerInputFormatter.cs b/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerInputFormatter.cs index ab3abdf801..667bf14c01 100644 --- a/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerInputFormatter.cs +++ b/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerInputFormatter.cs @@ -132,8 +132,8 @@ namespace Microsoft.AspNetCore.Mvc.Formatters try { - using var xmlReader = CreateXmlReader(readStream, encoding); - var type = GetSerializableType(context.ModelType); + var type = GetSerializableType(context.ModelType); + using var xmlReader = CreateXmlReader(readStream, encoding, type); var serializer = GetCachedSerializer(type); @@ -204,6 +204,18 @@ namespace Microsoft.AspNetCore.Mvc.Formatters return wrapperProvider?.WrappingType ?? declaredType; } + /// + /// Called during deserialization to get the . + /// + /// The from which to read. + /// The used to read the stream. + /// The that is to be deserialized. + /// The used during deserialization. + protected virtual XmlReader CreateXmlReader(Stream readStream, Encoding encoding, Type type) + { + return CreateXmlReader(readStream, encoding); + } + /// /// Called during deserialization to get the . /// diff --git a/src/Mvc/Mvc.Localization/ref/Microsoft.AspNetCore.Mvc.Localization.netcoreapp.cs b/src/Mvc/Mvc.Localization/ref/Microsoft.AspNetCore.Mvc.Localization.netcoreapp.cs index c6a84e9236..58d007b3c7 100644 --- a/src/Mvc/Mvc.Localization/ref/Microsoft.AspNetCore.Mvc.Localization.netcoreapp.cs +++ b/src/Mvc/Mvc.Localization/ref/Microsoft.AspNetCore.Mvc.Localization.netcoreapp.cs @@ -13,8 +13,6 @@ namespace Microsoft.AspNetCore.Mvc.Localization public virtual Microsoft.Extensions.Localization.LocalizedString GetString(string name, params object[] arguments) { throw null; } protected virtual Microsoft.AspNetCore.Mvc.Localization.LocalizedHtmlString ToHtmlString(Microsoft.Extensions.Localization.LocalizedString result) { throw null; } protected virtual Microsoft.AspNetCore.Mvc.Localization.LocalizedHtmlString ToHtmlString(Microsoft.Extensions.Localization.LocalizedString result, object[] arguments) { throw null; } - [System.ObsoleteAttribute("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - public virtual Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer WithCulture(System.Globalization.CultureInfo culture) { throw null; } } public static partial class HtmlLocalizerExtensions { @@ -36,8 +34,6 @@ namespace Microsoft.AspNetCore.Mvc.Localization public virtual System.Collections.Generic.IEnumerable GetAllStrings(bool includeParentCultures) { throw null; } public virtual Microsoft.Extensions.Localization.LocalizedString GetString(string name) { throw null; } public virtual Microsoft.Extensions.Localization.LocalizedString GetString(string name, params object[] arguments) { throw null; } - [System.ObsoleteAttribute("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - public virtual Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer WithCulture(System.Globalization.CultureInfo culture) { throw null; } } public partial interface IHtmlLocalizer { @@ -46,8 +42,6 @@ namespace Microsoft.AspNetCore.Mvc.Localization System.Collections.Generic.IEnumerable GetAllStrings(bool includeParentCultures); Microsoft.Extensions.Localization.LocalizedString GetString(string name); Microsoft.Extensions.Localization.LocalizedString GetString(string name, params object[] arguments); - [System.ObsoleteAttribute("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer WithCulture(System.Globalization.CultureInfo culture); } public partial interface IHtmlLocalizerFactory { @@ -65,9 +59,9 @@ namespace Microsoft.AspNetCore.Mvc.Localization public LocalizedHtmlString(string name, string value) { } public LocalizedHtmlString(string name, string value, bool isResourceNotFound) { } public LocalizedHtmlString(string name, string value, bool isResourceNotFound, params object[] arguments) { } - public bool IsResourceNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsResourceNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void WriteTo(System.IO.TextWriter writer, System.Text.Encodings.Web.HtmlEncoder encoder) { } } public partial class ViewLocalizer : Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer, Microsoft.AspNetCore.Mvc.Localization.IViewLocalizer, Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware @@ -79,8 +73,6 @@ namespace Microsoft.AspNetCore.Mvc.Localization public System.Collections.Generic.IEnumerable GetAllStrings(bool includeParentCultures) { throw null; } public Microsoft.Extensions.Localization.LocalizedString GetString(string name) { throw null; } public Microsoft.Extensions.Localization.LocalizedString GetString(string name, params object[] values) { throw null; } - [System.ObsoleteAttribute("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - public Microsoft.AspNetCore.Mvc.Localization.IHtmlLocalizer WithCulture(System.Globalization.CultureInfo culture) { throw null; } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Mvc/Mvc.Localization/src/HtmlLocalizer.cs b/src/Mvc/Mvc.Localization/src/HtmlLocalizer.cs index 7e95771fa5..eca0387cf6 100644 --- a/src/Mvc/Mvc.Localization/src/HtmlLocalizer.cs +++ b/src/Mvc/Mvc.Localization/src/HtmlLocalizer.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using Microsoft.Extensions.Localization; namespace Microsoft.AspNetCore.Mvc.Localization @@ -84,20 +83,6 @@ namespace Microsoft.AspNetCore.Mvc.Localization public virtual IEnumerable GetAllStrings(bool includeParentCultures) => _localizer.GetAllStrings(includeParentCultures); - /// - [Obsolete("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - public virtual IHtmlLocalizer WithCulture(CultureInfo culture) - { - if (culture == null) - { - throw new ArgumentNullException(nameof(culture)); - } - -#pragma warning disable CS0618 // Type or member is obsolete - return new HtmlLocalizer(_localizer.WithCulture(culture)); -#pragma warning restore CS0618 // Type or member is obsolete - } - /// /// Creates a new for a . /// diff --git a/src/Mvc/Mvc.Localization/src/HtmlLocalizerOfT.cs b/src/Mvc/Mvc.Localization/src/HtmlLocalizerOfT.cs index 736a1af6af..114cc3fa8e 100644 --- a/src/Mvc/Mvc.Localization/src/HtmlLocalizerOfT.cs +++ b/src/Mvc/Mvc.Localization/src/HtmlLocalizerOfT.cs @@ -79,19 +79,5 @@ namespace Microsoft.AspNetCore.Mvc.Localization /// public virtual IEnumerable GetAllStrings(bool includeParentCultures) => _localizer.GetAllStrings(includeParentCultures); - - /// - [Obsolete("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - public virtual IHtmlLocalizer WithCulture(CultureInfo culture) - { - if (culture == null) - { - throw new ArgumentNullException(nameof(culture)); - } - -#pragma warning disable CS0618 // Type or member is obsolete - return _localizer.WithCulture(culture); -#pragma warning restore CS0618 // Type or member is obsolete - } } } diff --git a/src/Mvc/Mvc.Localization/src/IHtmlLocalizer.cs b/src/Mvc/Mvc.Localization/src/IHtmlLocalizer.cs index 0b41530fc5..180025b796 100644 --- a/src/Mvc/Mvc.Localization/src/IHtmlLocalizer.cs +++ b/src/Mvc/Mvc.Localization/src/IHtmlLocalizer.cs @@ -53,13 +53,5 @@ namespace Microsoft.AspNetCore.Mvc.Localization /// /// The strings. IEnumerable GetAllStrings(bool includeParentCultures); - - /// - /// Creates a new for a specific . - /// - /// The to use. - /// A culture-specific . - [Obsolete("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - IHtmlLocalizer WithCulture(CultureInfo culture); } } diff --git a/src/Mvc/Mvc.Localization/src/ViewLocalizer.cs b/src/Mvc/Mvc.Localization/src/ViewLocalizer.cs index 72a47f5551..29401fe5df 100644 --- a/src/Mvc/Mvc.Localization/src/ViewLocalizer.cs +++ b/src/Mvc/Mvc.Localization/src/ViewLocalizer.cs @@ -79,13 +79,6 @@ namespace Microsoft.AspNetCore.Mvc.Localization /// public LocalizedString GetString(string name, params object[] values) => _localizer.GetString(name, values); - /// - [Obsolete("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")] - -#pragma warning disable CS0618 // Type or member is obsolete - public IHtmlLocalizer WithCulture(CultureInfo culture) => _localizer.WithCulture(culture); -#pragma warning restore CS0618 // Type or member is obsolete - /// public IEnumerable GetAllStrings(bool includeParentCultures) => _localizer.GetAllStrings(includeParentCultures); diff --git a/src/Mvc/Mvc.Localization/test/HtmlLocalizerTest.cs b/src/Mvc/Mvc.Localization/test/HtmlLocalizerTest.cs index 64dcfd9c31..ce78021044 100644 --- a/src/Mvc/Mvc.Localization/test/HtmlLocalizerTest.cs +++ b/src/Mvc/Mvc.Localization/test/HtmlLocalizerTest.cs @@ -207,14 +207,12 @@ namespace Microsoft.AspNetCore.Mvc.Localization.Test public void HtmlLocalizer_WithCulture_ReturnsLocalizedHtmlString() { // Arrange - var stringLocalizer = new TestStringLocalizer(); + var stringLocalizer = new TestStringLocalizer(new CultureInfo("fr")); var htmlLocalizer = new HtmlLocalizer(stringLocalizer); // Act -#pragma warning disable CS0618 // Type or member is obsolete - var actualLocalizedHtmlString = htmlLocalizer.WithCulture(new CultureInfo("fr"))["John"]; -#pragma warning restore CS0618 // Type or member is obsolete + var actualLocalizedHtmlString = htmlLocalizer["John"]; // Assert Assert.Equal("Bonjour John", actualLocalizedHtmlString.Value); diff --git a/src/Mvc/Mvc.Localization/test/ViewLocalizerTest.cs b/src/Mvc/Mvc.Localization/test/ViewLocalizerTest.cs index 529dfbd744..7f1dc5df2b 100644 --- a/src/Mvc/Mvc.Localization/test/ViewLocalizerTest.cs +++ b/src/Mvc/Mvc.Localization/test/ViewLocalizerTest.cs @@ -266,7 +266,7 @@ namespace Microsoft.AspNetCore.Mvc.Localization.Test public void ViewLocalizer_WithCulture_ReturnsLocalizedHtmlString() { // Arrange - var stringLocalizer = new TestStringLocalizer(); + var stringLocalizer = new TestStringLocalizer(new CultureInfo("fr")); var htmlLocalizer = new HtmlLocalizer(stringLocalizer); var hostingEnvironment = new Mock(); hostingEnvironment.Setup(a => a.ApplicationName).Returns("TestApplication"); @@ -280,9 +280,7 @@ namespace Microsoft.AspNetCore.Mvc.Localization.Test viewLocalizer.Contextualize(viewContext); // Act -#pragma warning disable CS0618 // Type or member is obsolete - var actualLocalizedString = viewLocalizer.WithCulture(new CultureInfo("fr"))["John"]; -#pragma warning restore CS0618 // Type or member is obsolete + var actualLocalizedString = htmlLocalizer["John"]; // Assert Assert.Equal("Bonjour John", actualLocalizedString.Value); diff --git a/src/Mvc/Mvc.NewtonsoftJson/ref/Microsoft.AspNetCore.Mvc.NewtonsoftJson.netcoreapp.cs b/src/Mvc/Mvc.NewtonsoftJson/ref/Microsoft.AspNetCore.Mvc.NewtonsoftJson.netcoreapp.cs index 94884372e6..1fdaa0ae97 100644 --- a/src/Mvc/Mvc.NewtonsoftJson/ref/Microsoft.AspNetCore.Mvc.NewtonsoftJson.netcoreapp.cs +++ b/src/Mvc/Mvc.NewtonsoftJson/ref/Microsoft.AspNetCore.Mvc.NewtonsoftJson.netcoreapp.cs @@ -11,8 +11,8 @@ namespace Microsoft.AspNetCore.Mvc public partial class MvcNewtonsoftJsonOptions : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { public MvcNewtonsoftJsonOptions() { } - public bool AllowInputFormatterExceptionMessages { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Newtonsoft.Json.JsonSerializerSettings SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AllowInputFormatterExceptionMessages { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Newtonsoft.Json.JsonSerializerSettings SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters { public NewtonsoftJsonInputFormatter(Microsoft.Extensions.Logging.ILogger logger, Newtonsoft.Json.JsonSerializerSettings serializerSettings, System.Buffers.ArrayPool charPool, Microsoft.Extensions.ObjectPool.ObjectPoolProvider objectPoolProvider, Microsoft.AspNetCore.Mvc.MvcOptions options, Microsoft.AspNetCore.Mvc.MvcNewtonsoftJsonOptions jsonOptions) { } public virtual Microsoft.AspNetCore.Mvc.Formatters.InputFormatterExceptionPolicy ExceptionPolicy { get { throw null; } } - protected Newtonsoft.Json.JsonSerializerSettings SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Newtonsoft.Json.JsonSerializerSettings SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected virtual Newtonsoft.Json.JsonSerializer CreateJsonSerializer() { throw null; } protected virtual Newtonsoft.Json.JsonSerializer CreateJsonSerializer(Microsoft.AspNetCore.Mvc.Formatters.InputFormatterContext context) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters public partial class NewtonsoftJsonOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter { public NewtonsoftJsonOutputFormatter(Newtonsoft.Json.JsonSerializerSettings serializerSettings, System.Buffers.ArrayPool charPool, Microsoft.AspNetCore.Mvc.MvcOptions mvcOptions) { } - protected Newtonsoft.Json.JsonSerializerSettings SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Newtonsoft.Json.JsonSerializerSettings SerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected virtual Newtonsoft.Json.JsonSerializer CreateJsonSerializer() { throw null; } protected virtual Newtonsoft.Json.JsonSerializer CreateJsonSerializer(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context) { throw null; } protected virtual Newtonsoft.Json.JsonWriter CreateJsonWriter(System.IO.TextWriter writer) { throw null; } diff --git a/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonResultExecutor.cs b/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonResultExecutor.cs index eac7d6400a..a01ef805ae 100644 --- a/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonResultExecutor.cs +++ b/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonResultExecutor.cs @@ -3,7 +3,6 @@ using System; using System.Buffers; -using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Formatters; @@ -31,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson private readonly MvcOptions _mvcOptions; private readonly MvcNewtonsoftJsonOptions _jsonOptions; private readonly IArrayPool _charPool; - private readonly AsyncEnumerableReader _asyncEnumerableReader; + private readonly AsyncEnumerableReader _asyncEnumerableReaderFactory; /// /// Creates a new . @@ -73,7 +72,7 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson _mvcOptions = mvcOptions?.Value ?? throw new ArgumentNullException(nameof(mvcOptions)); _jsonOptions = jsonOptions.Value; _charPool = new JsonArrayPool(charPool); - _asyncEnumerableReader = new AsyncEnumerableReader(_mvcOptions); + _asyncEnumerableReaderFactory = new AsyncEnumerableReader(_mvcOptions); } /// @@ -133,10 +132,10 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson var jsonSerializer = JsonSerializer.Create(jsonSerializerSettings); var value = result.Value; - if (result.Value is IAsyncEnumerable asyncEnumerable) + if (value != null && _asyncEnumerableReaderFactory.TryGetReader(value.GetType(), out var reader)) { - Log.BufferingAsyncEnumerable(_logger, asyncEnumerable); - value = await _asyncEnumerableReader.ReadAsync(asyncEnumerable); + Log.BufferingAsyncEnumerable(_logger, value); + value = await reader(value); } jsonSerializer.Serialize(jsonWriter, value); @@ -201,7 +200,7 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson _jsonResultExecuting(logger, type, null); } - public static void BufferingAsyncEnumerable(ILogger logger, IAsyncEnumerable asyncEnumerable) + public static void BufferingAsyncEnumerable(ILogger logger, object asyncEnumerable) => _bufferingAsyncEnumerable(logger, asyncEnumerable.GetType().FullName, null); } } diff --git a/src/Mvc/Mvc.Razor.RuntimeCompilation/ref/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.netcoreapp.cs b/src/Mvc/Mvc.Razor.RuntimeCompilation/ref/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.netcoreapp.cs index a22420cffc..286620cf66 100644 --- a/src/Mvc/Mvc.Razor.RuntimeCompilation/ref/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.netcoreapp.cs +++ b/src/Mvc/Mvc.Razor.RuntimeCompilation/ref/Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.netcoreapp.cs @@ -14,11 +14,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation { public FileProviderRazorProjectItem(Microsoft.Extensions.FileProviders.IFileInfo fileInfo, string basePath, string filePath, string root) { } public FileProviderRazorProjectItem(Microsoft.Extensions.FileProviders.IFileInfo fileInfo, string basePath, string filePath, string root, string fileKind) { } - public override string BasePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public override string BasePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override bool Exists { get { throw null; } } - public Microsoft.Extensions.FileProviders.IFileInfo FileInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override string FileKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override string FilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.FileProviders.IFileInfo FileInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override string FileKind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override string FilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string PhysicalPath { get { throw null; } } public override string RelativePhysicalPath { get { throw null; } } public override System.IO.Stream Read() { throw null; } @@ -26,8 +26,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation public partial class MvcRazorRuntimeCompilationOptions { public MvcRazorRuntimeCompilationOptions() { } - public System.Collections.Generic.IList AdditionalReferencePaths { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList FileProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList AdditionalReferencePaths { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList FileProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Mvc/Mvc.Razor/ref/Microsoft.AspNetCore.Mvc.Razor.netcoreapp.cs b/src/Mvc/Mvc.Razor/ref/Microsoft.AspNetCore.Mvc.Razor.netcoreapp.cs index d7bb661a5b..28c29522ca 100644 --- a/src/Mvc/Mvc.Razor/ref/Microsoft.AspNetCore.Mvc.Razor.netcoreapp.cs +++ b/src/Mvc/Mvc.Razor/ref/Microsoft.AspNetCore.Mvc.Razor.netcoreapp.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationParts public partial class CompiledRazorAssemblyPart : Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPart, Microsoft.AspNetCore.Mvc.ApplicationParts.IRazorCompiledItemProvider { public CompiledRazorAssemblyPart(System.Reflection.Assembly assembly) { } - public System.Reflection.Assembly Assembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Reflection.Assembly Assembly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Collections.Generic.IEnumerable Microsoft.AspNetCore.Mvc.ApplicationParts.IRazorCompiledItemProvider.CompiledItems { get { throw null; } } public override string Name { get { throw null; } } } @@ -27,23 +27,23 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics { public const string EventName = "Microsoft.AspNetCore.Mvc.Razor.AfterViewPage"; public AfterViewPageEventData(Microsoft.AspNetCore.Mvc.Razor.IRazorPage page, Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Http.HttpContext httpContext) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Razor.IRazorPage Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Razor.IRazorPage Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeViewPageEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.Razor.BeforeViewPage"; public BeforeViewPageEventData(Microsoft.AspNetCore.Mvc.Razor.IRazorPage page, Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Http.HttpContext httpContext) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Razor.IRazorPage Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Razor.IRazorPage Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.Razor @@ -134,21 +134,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor public abstract partial class RazorPageBase : Microsoft.AspNetCore.Mvc.Razor.IRazorPage { protected RazorPageBase() { } - public Microsoft.AspNetCore.Html.IHtmlContent BodyContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Html.IHtmlContent BodyContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] - public System.Diagnostics.DiagnosticSource DiagnosticSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Diagnostics.DiagnosticSource DiagnosticSource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] - public System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool IsLayoutBeingRendered { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Layout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool IsLayoutBeingRendered { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Layout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.IO.TextWriter Output { get { throw null; } } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary PreviousSectionWriters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary SectionWriters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary PreviousSectionWriters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary SectionWriters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { get { throw null; } } public virtual System.Security.Claims.ClaimsPrincipal User { get { throw null; } } public dynamic ViewBag { get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void AddHtmlAttributeValue(string prefix, int prefixOffset, object value, int valueOffset, int valueLength, bool isLiteral) { } public void BeginAddHtmlAttributeValues(Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext executionContext, string attributeName, int attributeValuesCount, Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle attributeValueStyle) { } public abstract void BeginContext(int position, int length, bool isLiteral); @@ -184,34 +184,36 @@ namespace Microsoft.AspNetCore.Mvc.Razor public readonly partial struct RazorPageFactoryResult { private readonly object _dummy; + private readonly int _dummyPrimitive; public RazorPageFactoryResult(Microsoft.AspNetCore.Mvc.Razor.Compilation.CompiledViewDescriptor viewDescriptor, System.Func razorPageFactory) { throw null; } - public System.Func RazorPageFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Func RazorPageFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Success { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Razor.Compilation.CompiledViewDescriptor ViewDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Razor.Compilation.CompiledViewDescriptor ViewDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct RazorPageResult { private readonly object _dummy; + private readonly int _dummyPrimitive; public RazorPageResult(string name, Microsoft.AspNetCore.Mvc.Razor.IRazorPage page) { throw null; } public RazorPageResult(string name, System.Collections.Generic.IEnumerable searchedLocations) { throw null; } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Razor.IRazorPage Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IEnumerable SearchedLocations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Razor.IRazorPage Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IEnumerable SearchedLocations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class RazorPage : Microsoft.AspNetCore.Mvc.Razor.RazorPage { protected RazorPage() { } public TModel Model { get { throw null; } } [Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RazorView : Microsoft.AspNetCore.Mvc.ViewEngines.IView { public RazorView(Microsoft.AspNetCore.Mvc.Razor.IRazorViewEngine viewEngine, Microsoft.AspNetCore.Mvc.Razor.IRazorPageActivator pageActivator, System.Collections.Generic.IReadOnlyList viewStartPages, Microsoft.AspNetCore.Mvc.Razor.IRazorPage razorPage, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, System.Diagnostics.DiagnosticListener diagnosticListener) { } public string Path { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Razor.IRazorPage RazorPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList ViewStartPages { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Razor.IRazorPage RazorPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList ViewStartPages { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task RenderAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext context) { throw null; } } @@ -219,7 +221,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor { public static readonly string ViewExtension; public RazorViewEngine(Microsoft.AspNetCore.Mvc.Razor.IRazorPageFactoryProvider pageFactory, Microsoft.AspNetCore.Mvc.Razor.IRazorPageActivator pageActivator, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, Microsoft.Extensions.Options.IOptions optionsAccessor, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.Diagnostics.DiagnosticListener diagnosticListener) { } - protected Microsoft.Extensions.Caching.Memory.IMemoryCache ViewLookupCache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Caching.Memory.IMemoryCache ViewLookupCache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.Razor.RazorPageResult FindPage(Microsoft.AspNetCore.Mvc.ActionContext context, string pageName) { throw null; } public Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult FindView(Microsoft.AspNetCore.Mvc.ActionContext context, string viewName, bool isMainPage) { throw null; } public string GetAbsolutePath(string executingFilePath, string pagePath) { throw null; } @@ -230,11 +232,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor public partial class RazorViewEngineOptions { public RazorViewEngineOptions() { } - public System.Collections.Generic.IList AreaPageViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList AreaViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList PageViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList ViewLocationExpanders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList ViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList AreaPageViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList AreaViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList PageViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList ViewLocationExpanders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList ViewLocationFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public delegate System.Threading.Tasks.Task RenderAsyncDelegate(); public partial class TagHelperInitializer : Microsoft.AspNetCore.Mvc.Razor.ITagHelperInitializer where TTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper @@ -245,13 +247,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor public partial class ViewLocationExpanderContext { public ViewLocationExpanderContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, string viewName, string controllerName, string areaName, string pageName, bool isMainPage) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string AreaName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsMainPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string PageName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string AreaName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ControllerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsMainPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string PageName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.Razor.Compilation @@ -261,12 +263,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Compilation public CompiledViewDescriptor() { } public CompiledViewDescriptor(Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItem item) { } public CompiledViewDescriptor(Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItem item, Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute attribute) { } - public System.Collections.Generic.IList ExpirationTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItem Item { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList ExpirationTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItem Item { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Type Type { get { throw null; } } [System.ObsoleteAttribute("Use Item instead. RazorViewAttribute has been superseded by RazorCompiledItem and will not be used by the runtime.")] - public Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute ViewAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute ViewAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IViewCompiler { @@ -281,13 +283,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Compilation public partial class RazorViewAttribute : System.Attribute { public RazorViewAttribute(string path, System.Type viewType) { } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type ViewType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type ViewType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ViewsFeature { public ViewsFeature() { } - public System.Collections.Generic.IList ViewDescriptors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ViewDescriptors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.Razor.Infrastructure @@ -295,7 +297,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Infrastructure public sealed partial class TagHelperMemoryCacheProvider { public TagHelperMemoryCacheProvider() { } - public Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.Razor.Internal @@ -332,10 +334,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers { public TagHelperComponentTagHelper(Microsoft.AspNetCore.Mvc.Razor.TagHelpers.ITagHelperComponentManager manager, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Razor.TagHelpers.ITagHelperComponentPropertyActivator PropertyActivator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Razor.TagHelpers.ITagHelperComponentPropertyActivator PropertyActivator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Init(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context) { } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } @@ -343,7 +345,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers public partial class TagHelperFeature { public TagHelperFeature() { } - public System.Collections.Generic.IList TagHelpers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList TagHelpers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class TagHelperFeatureProvider : Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationFeatureProvider, Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationFeatureProvider { @@ -384,12 +386,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers public partial class UrlResolutionTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper { public UrlResolutionTagHelper(Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory urlHelperFactory, System.Text.Encodings.Web.HtmlEncoder htmlEncoder) { } - protected System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } - protected Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory UrlHelperFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory UrlHelperFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } protected void ProcessUrlAttribute(string attributeName, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } protected bool TryResolveUrl(string url, out Microsoft.AspNetCore.Html.IHtmlContent resolvedUrl) { throw null; } diff --git a/src/Mvc/Mvc.Razor/src/Internal/RazorInjectAttribute.cs b/src/Mvc/Mvc.Razor/src/Internal/RazorInjectAttribute.cs index a981e6eb66..7f1c211da3 100644 --- a/src/Mvc/Mvc.Razor/src/Internal/RazorInjectAttribute.cs +++ b/src/Mvc/Mvc.Razor/src/Internal/RazorInjectAttribute.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal /// /// Specifies that the attributed property should be bound using request services. /// - /// This attribute is used as the backing attribute for the @inject + /// This attribute is used as the backing attribute for the @inject /// Razor directive. /// /// diff --git a/src/Mvc/Mvc.RazorPages/ref/Directory.Build.props b/src/Mvc/Mvc.RazorPages/ref/Directory.Build.props index bae646f06c..6cab2bf950 100644 --- a/src/Mvc/Mvc.RazorPages/ref/Directory.Build.props +++ b/src/Mvc/Mvc.RazorPages/ref/Directory.Build.props @@ -3,7 +3,7 @@ - + diff --git a/src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp.cs b/src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp.cs index e8959d832a..b93e1462ed 100644 --- a/src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp.cs +++ b/src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp.cs @@ -59,18 +59,18 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels public PageApplicationModel(Microsoft.AspNetCore.Mvc.ApplicationModels.PageApplicationModel other) { } public PageApplicationModel(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor, System.Reflection.TypeInfo handlerType, System.Collections.Generic.IReadOnlyList handlerAttributes) { } public PageApplicationModel(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor, System.Reflection.TypeInfo declaredModelType, System.Reflection.TypeInfo handlerType, System.Collections.Generic.IReadOnlyList handlerAttributes) { } - public Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string AreaName { get { throw null; } } - public System.Reflection.TypeInfo DeclaredModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList EndpointMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList HandlerMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList HandlerProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Reflection.TypeInfo HandlerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList HandlerTypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Reflection.TypeInfo ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Reflection.TypeInfo DeclaredModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList EndpointMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Filters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList HandlerMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList HandlerProperties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Reflection.TypeInfo HandlerType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList HandlerTypeAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Reflection.TypeInfo ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string RelativePath { get { throw null; } } public string RouteTemplate { get { throw null; } } public string ViewEnginePath { get { throw null; } } @@ -78,9 +78,9 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels public partial class PageApplicationModelProviderContext { public PageApplicationModelProviderContext(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor descriptor, System.Reflection.TypeInfo pageTypeInfo) { } - public Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.PageApplicationModel PageApplicationModel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.PageApplicationModel PageApplicationModel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo PageType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class PageConventionCollection : System.Collections.ObjectModel.Collection { @@ -102,39 +102,39 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels { public PageHandlerModel(Microsoft.AspNetCore.Mvc.ApplicationModels.PageHandlerModel other) { } public PageHandlerModel(System.Reflection.MethodInfo handlerMethod, System.Collections.Generic.IReadOnlyList attributes) { } - public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string HandlerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string HandlerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Reflection.MemberInfo Microsoft.AspNetCore.Mvc.ApplicationModels.ICommonModel.MemberInfo { get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ApplicationModels.PageApplicationModel Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.PageApplicationModel Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class PageRouteMetadata { public PageRouteMetadata(string pageRoute, string routeTemplate) { } - public string PageRoute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string PageRoute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class PageRouteModel { public PageRouteModel(Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteModel other) { } public PageRouteModel(string relativePath, string viewEnginePath) { } public PageRouteModel(string relativePath, string viewEnginePath, string areaName) { } - public string AreaName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Routing.IOutboundParameterTransformer RouteParameterTransformer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IList Selectors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ViewEnginePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AreaName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Routing.IOutboundParameterTransformer RouteParameterTransformer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IDictionary RouteValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IList Selectors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ViewEnginePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class PageRouteModelProviderContext { public PageRouteModelProviderContext() { } - public System.Collections.Generic.IList RouteModels { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList RouteModels { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class PageRouteTransformerConvention : Microsoft.AspNetCore.Mvc.ApplicationModels.IPageConvention, Microsoft.AspNetCore.Mvc.ApplicationModels.IPageRouteModelConvention { @@ -149,123 +149,123 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterHandlerMethod"; public AfterHandlerMethodEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IReadOnlyDictionary arguments, Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor handlerMethodDescriptor, object instance, Microsoft.AspNetCore.Mvc.IActionResult result) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethodDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethodDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterPageFilterOnPageHandlerExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnPageHandlerExecuted"; public AfterPageFilterOnPageHandlerExecutedEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext handlerExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext HandlerExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext HandlerExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterPageFilterOnPageHandlerExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnPageHandlerExecuting"; public AfterPageFilterOnPageHandlerExecutingEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext handlerExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext HandlerExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext HandlerExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterPageFilterOnPageHandlerExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnPageHandlerExecution"; public AfterPageFilterOnPageHandlerExecutionEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext handlerExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext HandlerExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext HandlerExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterPageFilterOnPageHandlerSelectedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnPageHandlerSelected"; public AfterPageFilterOnPageHandlerSelectedEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext handlerSelectedContext, Microsoft.AspNetCore.Mvc.Filters.IPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class AfterPageFilterOnPageHandlerSelectionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterOnPageHandlerSelection"; public AfterPageFilterOnPageHandlerSelectionEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext handlerSelectedContext, Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforeHandlerMethodEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeHandlerMethod"; public BeforeHandlerMethodEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, System.Collections.Generic.IReadOnlyDictionary arguments, Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor handlerMethodDescriptor, object instance) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethodDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethodDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Instance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforePageFilterOnPageHandlerExecutedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnPageHandlerExecuted"; public BeforePageFilterOnPageHandlerExecutedEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext handlerExecutedContext, Microsoft.AspNetCore.Mvc.Filters.IPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext HandlerExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutedContext HandlerExecutedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforePageFilterOnPageHandlerExecutingEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnPageHandlerExecuting"; public BeforePageFilterOnPageHandlerExecutingEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext handlerExecutingContext, Microsoft.AspNetCore.Mvc.Filters.IPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext HandlerExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext HandlerExecutingContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforePageFilterOnPageHandlerExecutionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnPageHandlerExecution"; public BeforePageFilterOnPageHandlerExecutionEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext handlerExecutionContext, Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext HandlerExecutionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerExecutingContext HandlerExecutionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforePageFilterOnPageHandlerSelectedEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnPageHandlerSelected"; public BeforePageFilterOnPageHandlerSelectedEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext handlerSelectedContext, Microsoft.AspNetCore.Mvc.Filters.IPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } public sealed partial class BeforePageFilterOnPageHandlerSelectionEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeOnPageHandlerSelection"; public BeforePageFilterOnPageHandlerSelectionEventData(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext handlerSelectedContext, Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter filter) { } - public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.IAsyncPageFilter Filter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Filters.PageHandlerSelectedContext HandlerSelectedContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } } } @@ -286,30 +286,30 @@ namespace Microsoft.AspNetCore.Mvc.Filters { public PageHandlerExecutedContext(Microsoft.AspNetCore.Mvc.RazorPages.PageContext pageContext, System.Collections.Generic.IList filters, Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor handlerMethod, object handlerInstance) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } public virtual new Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { get { throw null; } } - public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool Canceled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Exception Exception { get { throw null; } set { } } public virtual System.Runtime.ExceptionServices.ExceptionDispatchInfo ExceptionDispatchInfo { get { throw null; } set { } } - public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual object HandlerInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual bool ExceptionHandled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual object HandlerInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PageHandlerExecutingContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public PageHandlerExecutingContext(Microsoft.AspNetCore.Mvc.RazorPages.PageContext pageContext, System.Collections.Generic.IList filters, Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor handlerMethod, System.Collections.Generic.IDictionary handlerArguments, object handlerInstance) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } public virtual new Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { get { throw null; } } - public virtual System.Collections.Generic.IDictionary HandlerArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual object HandlerInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Collections.Generic.IDictionary HandlerArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual object HandlerInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.IActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public delegate System.Threading.Tasks.Task PageHandlerExecutionDelegate(); public partial class PageHandlerSelectedContext : Microsoft.AspNetCore.Mvc.Filters.FilterContext { public PageHandlerSelectedContext(Microsoft.AspNetCore.Mvc.RazorPages.PageContext pageContext, System.Collections.Generic.IList filters, object handlerInstance) : base (default(Microsoft.AspNetCore.Mvc.ActionContext), default(System.Collections.Generic.IList)) { } public virtual new Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor ActionDescriptor { get { throw null; } } - public virtual object HandlerInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual object HandlerInstance { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.HandlerMethodDescriptor HandlerMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Mvc.RazorPages @@ -318,12 +318,12 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages { public CompiledPageActionDescriptor() { } public CompiledPageActionDescriptor(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor) { } - public System.Reflection.TypeInfo DeclaredModelTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Endpoint Endpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList HandlerMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo HandlerTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo ModelTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo PageTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.TypeInfo DeclaredModelTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Endpoint Endpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList HandlerMethods { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo HandlerTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo ModelTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo PageTypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IPageActivatorProvider { @@ -359,10 +359,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages { public PageActionDescriptor() { } public PageActionDescriptor(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor other) { } - public string AreaName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AreaName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override string DisplayName { get { throw null; } set { } } - public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ViewEnginePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RelativePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ViewEnginePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class PageBase : Microsoft.AspNetCore.Mvc.Razor.RazorPageBase { @@ -370,11 +370,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } } public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { get { throw null; } set { } } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { get { throw null; } } - public Microsoft.AspNetCore.Mvc.RazorPages.PageContext PageContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.RazorPages.PageContext PageContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.HttpRequest Request { get { throw null; } } public Microsoft.AspNetCore.Http.HttpResponse Response { get { throw null; } } public Microsoft.AspNetCore.Routing.RouteData RouteData { get { throw null; } } - public override Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public override Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual Microsoft.AspNetCore.Mvc.BadRequestResult BadRequest() { throw null; } public virtual Microsoft.AspNetCore.Mvc.BadRequestObjectResult BadRequest(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) { throw null; } public virtual Microsoft.AspNetCore.Mvc.BadRequestObjectResult BadRequest(object error) { throw null; } @@ -627,17 +627,17 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages public partial class PageResult : Microsoft.AspNetCore.Mvc.ActionResult { public PageResult() { } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public object Model { get { throw null; } } - public Microsoft.AspNetCore.Mvc.RazorPages.PageBase Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.RazorPages.PageBase Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } public partial class RazorPagesOptions : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { public RazorPagesOptions() { } - public Microsoft.AspNetCore.Mvc.ApplicationModels.PageConventionCollection Conventions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ApplicationModels.PageConventionCollection Conventions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string RootDirectory { get { throw null; } set { } } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } @@ -648,15 +648,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure public partial class HandlerMethodDescriptor { public HandlerMethodDescriptor() { } - public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HandlerParameterDescriptor : Microsoft.AspNetCore.Mvc.Abstractions.ParameterDescriptor, Microsoft.AspNetCore.Mvc.Infrastructure.IParameterInfoParameterDescriptor { public HandlerParameterDescriptor() { } - public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IPageHandlerMethodSelector { @@ -670,7 +670,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure public partial class PageActionDescriptorProvider : Microsoft.AspNetCore.Mvc.Abstractions.IActionDescriptorProvider { public PageActionDescriptorProvider(System.Collections.Generic.IEnumerable pageRouteModelProviders, Microsoft.Extensions.Options.IOptions mvcOptionsAccessor, Microsoft.Extensions.Options.IOptions pagesOptionsAccessor) { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected System.Collections.Generic.IList BuildModel() { throw null; } public void OnProvidersExecuted(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptorProviderContext context) { } public void OnProvidersExecuting(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptorProviderContext context) { } @@ -679,7 +679,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure { public PageBoundPropertyDescriptor() { } System.Reflection.PropertyInfo Microsoft.AspNetCore.Mvc.Infrastructure.IPropertyInfoParameterDescriptor.PropertyInfo { get { throw null; } } - public System.Reflection.PropertyInfo Property { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Reflection.PropertyInfo Property { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class PageLoader : Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.IPageLoader { @@ -720,7 +720,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure public partial class RazorPageAttribute : Microsoft.AspNetCore.Mvc.Razor.Compilation.RazorViewAttribute { public RazorPageAttribute(string path, System.Type viewType, string routeTemplate) : base (default(string), default(System.Type)) { } - public string RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string RouteTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ServiceBasedPageModelActivatorProvider : Microsoft.AspNetCore.Mvc.RazorPages.IPageModelActivatorProvider { diff --git a/src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp3.1.Manual.cs b/src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp5.0.Manual.cs similarity index 100% rename from src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp3.1.Manual.cs rename to src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp5.0.Manual.cs diff --git a/src/Mvc/Mvc.RazorPages/src/ApplicationModels/PageRouteMetadata.cs b/src/Mvc/Mvc.RazorPages/src/ApplicationModels/PageRouteMetadata.cs index 46d86127cc..7f145c2dd1 100644 --- a/src/Mvc/Mvc.RazorPages/src/ApplicationModels/PageRouteMetadata.cs +++ b/src/Mvc/Mvc.RazorPages/src/ApplicationModels/PageRouteMetadata.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels /// /// Metadata used to construct an endpoint route to the page. /// - // Note: This type name is referenced by name in AuthorizationMiddleware, do not change this without addressing https://github.com/aspnet/AspNetCore/issues/7011 + // Note: This type name is referenced by name in AuthorizationMiddleware, do not change this without addressing https://github.com/dotnet/aspnetcore/issues/7011 public sealed class PageRouteMetadata { /// diff --git a/src/Mvc/Mvc.TagHelpers/ref/Microsoft.AspNetCore.Mvc.TagHelpers.netcoreapp.cs b/src/Mvc/Mvc.TagHelpers/ref/Microsoft.AspNetCore.Mvc.TagHelpers.netcoreapp.cs index 0523596d7e..2f9465e99b 100644 --- a/src/Mvc/Mvc.TagHelpers/ref/Microsoft.AspNetCore.Mvc.TagHelpers.netcoreapp.cs +++ b/src/Mvc/Mvc.TagHelpers/ref/Microsoft.AspNetCore.Mvc.TagHelpers.netcoreapp.cs @@ -27,39 +27,39 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public AnchorTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-action")] - public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-area")] - public string Area { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Area { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-controller")] - public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fragment")] - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-host")] - public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-page")] - public string Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-page-handler")] - public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-protocol")] - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-route")] - public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-all-route-data", DictionaryAttributePrefix="asp-route-")] public System.Collections.Generic.IDictionary RouteValues { get { throw null; } set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } public partial class CacheTagHelper : Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelperBase { public static readonly string CacheKeyPrefix; public CacheTagHelper(Microsoft.AspNetCore.Mvc.TagHelpers.CacheTagHelperMemoryCacheFactory factory, System.Text.Encodings.Web.HtmlEncoder htmlEncoder) : base (default(System.Text.Encodings.Web.HtmlEncoder)) { } - protected Microsoft.Extensions.Caching.Memory.IMemoryCache MemoryCache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Caching.Memory.IMemoryCache MemoryCache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("priority")] - public Microsoft.Extensions.Caching.Memory.CacheItemPriority? Priority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.Extensions.Caching.Memory.CacheItemPriority? Priority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -68,56 +68,56 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers public static readonly System.TimeSpan DefaultExpiration; public CacheTagHelperBase(System.Text.Encodings.Web.HtmlEncoder htmlEncoder) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("enabled")] - public bool Enabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Enabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("expires-after")] - public System.TimeSpan? ExpiresAfter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan? ExpiresAfter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("expires-on")] - public System.DateTimeOffset? ExpiresOn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.DateTimeOffset? ExpiresOn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("expires-sliding")] - public System.TimeSpan? ExpiresSliding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.TimeSpan? ExpiresSliding { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by")] - public string VaryBy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string VaryBy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by-cookie")] - public string VaryByCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string VaryByCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by-culture")] - public bool VaryByCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool VaryByCulture { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by-header")] - public string VaryByHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string VaryByHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by-query")] - public string VaryByQuery { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string VaryByQuery { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by-route")] - public string VaryByRoute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string VaryByRoute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("vary-by-user")] - public bool VaryByUser { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool VaryByUser { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CacheTagHelperMemoryCacheFactory { public CacheTagHelperMemoryCacheFactory(Microsoft.Extensions.Options.IOptions options) { } - public Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class CacheTagHelperOptions { public CacheTagHelperOptions() { } - public long SizeLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public long SizeLimit { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("component", Attributes="type", TagStructure=Microsoft.AspNetCore.Razor.TagHelpers.TagStructure.WithoutEndTag)] public sealed partial class ComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper { public ComponentTagHelper() { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("type")] - public System.Type ComponentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Type ComponentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("params", DictionaryAttributePrefix="param-")] public System.Collections.Generic.IDictionary Parameters { get { throw null; } set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("render-mode")] public Microsoft.AspNetCore.Mvc.Rendering.RenderMode RenderMode { get { throw null; } set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -126,19 +126,19 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public static readonly string CacheKeyPrefix; public DistributedCacheTagHelper(Microsoft.AspNetCore.Mvc.TagHelpers.Cache.IDistributedCacheTagHelperService distributedCacheService, System.Text.Encodings.Web.HtmlEncoder htmlEncoder) : base (default(System.Text.Encodings.Web.HtmlEncoder)) { } - protected Microsoft.Extensions.Caching.Memory.IMemoryCache MemoryCache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Caching.Memory.IMemoryCache MemoryCache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("name")] - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } public partial class EnvironmentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper { public EnvironmentTagHelper(Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment) { } - public string Exclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Include { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Names { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Exclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Include { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Names { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } @@ -173,26 +173,26 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public FormActionTagHelper(Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory urlHelperFactory) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-action")] - public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-area")] - public string Area { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Area { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-controller")] - public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fragment")] - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-page")] - public string Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-page-handler")] - public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-route")] - public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-all-route-data", DictionaryAttributePrefix="asp-route-")] public System.Collections.Generic.IDictionary RouteValues { get { throw null; } set { } } - protected Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory UrlHelperFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory UrlHelperFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("form")] @@ -200,38 +200,38 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public FormTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-action")] - public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Action { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-antiforgery")] - public bool? Antiforgery { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool? Antiforgery { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-area")] - public string Area { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Area { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-controller")] - public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Controller { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fragment")] - public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Fragment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public string Method { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Method { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-page")] - public string Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Page { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-page-handler")] - public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-route")] - public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Route { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-all-route-data", DictionaryAttributePrefix="asp-route-")] public System.Collections.Generic.IDictionary RouteValues { get { throw null; } set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } public partial class GlobbingUrlBuilder { public GlobbingUrlBuilder(Microsoft.Extensions.FileProviders.IFileProvider fileProvider, Microsoft.Extensions.Caching.Memory.IMemoryCache cache, Microsoft.AspNetCore.Http.PathString requestPathBase) { } - public Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.PathString RequestPathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.Extensions.FileProviders.IFileProvider FileProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.PathString RequestPathBase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Collections.Generic.IReadOnlyList BuildUrlList(string staticUrl, string includePattern, string excludePattern) { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("img", Attributes="asp-append-version,src", TagStructure=Microsoft.AspNetCore.Razor.TagHelpers.TagStructure.WithoutEndTag)] @@ -242,14 +242,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers [Microsoft.Extensions.DependencyInjection.ActivatorUtilitiesConstructorAttribute] public ImageTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IFileVersionProvider fileVersionProvider, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory urlHelperFactory) : base (default(Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory), default(System.Text.Encodings.Web.HtmlEncoder)) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-append-version")] - public bool AppendVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AppendVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ObsoleteAttribute("This property is obsolete and will be removed in a future version.")] - protected internal Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected internal Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.ObsoleteAttribute("This property is obsolete and will be removed in a future version.")] - protected internal Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected internal Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("src")] - public string Src { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Src { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("input", Attributes="asp-for", TagStructure=Microsoft.AspNetCore.Razor.TagHelpers.TagStructure.WithoutEndTag)] @@ -257,18 +257,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public InputTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-for")] - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-format")] - public string Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("type")] - public string InputTypeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string InputTypeName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected string GetInputType(Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer modelExplorer, out string inputTypeHint) { throw null; } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } @@ -277,12 +277,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public LabelTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-for")] - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -299,43 +299,43 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public LinkTagHelper(Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment, Microsoft.AspNetCore.Mvc.Razor.Infrastructure.TagHelperMemoryCacheProvider cacheProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.IFileVersionProvider fileVersionProvider, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, System.Text.Encodings.Web.JavaScriptEncoder javaScriptEncoder, Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory urlHelperFactory) : base (default(Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory), default(System.Text.Encodings.Web.HtmlEncoder)) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-append-version")] - public bool? AppendVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected internal Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool? AppendVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected internal Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-href")] - public string FallbackHref { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackHref { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-href-exclude")] - public string FallbackHrefExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackHrefExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-href-include")] - public string FallbackHrefInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackHrefInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-test-class")] - public string FallbackTestClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackTestClass { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-test-property")] - public string FallbackTestProperty { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackTestProperty { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-test-value")] - public string FallbackTestValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected internal Microsoft.AspNetCore.Mvc.TagHelpers.GlobbingUrlBuilder GlobbingUrlBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected internal Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FallbackTestValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected internal Microsoft.AspNetCore.Mvc.TagHelpers.GlobbingUrlBuilder GlobbingUrlBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected internal Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("href")] - public string Href { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Href { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-href-exclude")] - public string HrefExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string HrefExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-href-include")] - public string HrefInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected System.Text.Encodings.Web.JavaScriptEncoder JavaScriptEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string HrefInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected System.Text.Encodings.Web.JavaScriptEncoder JavaScriptEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-suppress-fallback-integrity")] - public bool SuppressFallbackIntegrity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SuppressFallbackIntegrity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } public partial class OptionTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper { public OptionTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -344,18 +344,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public PartialTagHelper(Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.IViewBufferScope viewBufferScope) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("fallback-name")] - public string FallbackName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("for")] public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { get { throw null; } set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("model")] public object Model { get { throw null; } set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("optional")] - public bool Optional { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Optional { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -367,7 +367,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers public override int Order { get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Init(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context) { } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } @@ -383,28 +383,28 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public ScriptTagHelper(Microsoft.AspNetCore.Hosting.IWebHostEnvironment hostingEnvironment, Microsoft.AspNetCore.Mvc.Razor.Infrastructure.TagHelperMemoryCacheProvider cacheProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.IFileVersionProvider fileVersionProvider, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, System.Text.Encodings.Web.JavaScriptEncoder javaScriptEncoder, Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory urlHelperFactory) : base (default(Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory), default(System.Text.Encodings.Web.HtmlEncoder)) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-append-version")] - public bool? AppendVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected internal Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool? AppendVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected internal Microsoft.Extensions.Caching.Memory.IMemoryCache Cache { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-src")] - public string FallbackSrc { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackSrc { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-src-exclude")] - public string FallbackSrcExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackSrcExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-src-include")] - public string FallbackSrcInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FallbackSrcInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-fallback-test")] - public string FallbackTestExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected internal Microsoft.AspNetCore.Mvc.TagHelpers.GlobbingUrlBuilder GlobbingUrlBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected internal Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected System.Text.Encodings.Web.JavaScriptEncoder JavaScriptEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FallbackTestExpression { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected internal Microsoft.AspNetCore.Mvc.TagHelpers.GlobbingUrlBuilder GlobbingUrlBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected internal Microsoft.AspNetCore.Hosting.IWebHostEnvironment HostingEnvironment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected System.Text.Encodings.Web.JavaScriptEncoder JavaScriptEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("src")] - public string Src { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Src { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-src-exclude")] - public string SrcExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string SrcExclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-src-include")] - public string SrcInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string SrcInclude { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-suppress-fallback-integrity")] - public bool SuppressFallbackIntegrity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SuppressFallbackIntegrity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("select", Attributes="asp-for")] @@ -413,15 +413,15 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public SelectTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-for")] - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-items")] - public System.Collections.Generic.IEnumerable Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IEnumerable Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Init(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context) { } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } @@ -438,13 +438,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public TextAreaTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-for")] - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("span", Attributes="asp-validation-for")] @@ -452,12 +452,12 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public ValidationMessageTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-validation-for")] - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } } @@ -466,13 +466,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public ValidationSummaryTagHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator generator) { } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator Generator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int Order { get { throw null; } } [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNameAttribute("asp-validation-summary")] public Microsoft.AspNetCore.Mvc.Rendering.ValidationSummary ValidationSummary { get { throw null; } set { } } [Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute] [Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute] - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } } } @@ -497,7 +497,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache public partial class DistributedCacheTagHelperFormattingContext { public DistributedCacheTagHelperFormattingContext() { } - public Microsoft.AspNetCore.Html.HtmlString Html { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Html.HtmlString Html { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DistributedCacheTagHelperService : Microsoft.AspNetCore.Mvc.TagHelpers.Cache.IDistributedCacheTagHelperService { diff --git a/src/Mvc/Mvc.TagHelpers/src/InputTagHelper.cs b/src/Mvc/Mvc.TagHelpers/src/InputTagHelper.cs index d3df4d963d..3ce7506e08 100644 --- a/src/Mvc/Mvc.TagHelpers/src/InputTagHelper.cs +++ b/src/Mvc/Mvc.TagHelpers/src/InputTagHelper.cs @@ -309,29 +309,32 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers "checkbox")); } - // hiddenForCheckboxTag always rendered after the returned element - var hiddenForCheckboxTag = Generator.GenerateHiddenForCheckbox(ViewContext, modelExplorer, For.Name); - if (hiddenForCheckboxTag != null) + if (ViewContext.CheckBoxHiddenInputRenderMode != CheckBoxHiddenInputRenderMode.None) { - var renderingMode = - output.TagMode == TagMode.SelfClosing ? TagRenderMode.SelfClosing : TagRenderMode.StartTag; - hiddenForCheckboxTag.TagRenderMode = renderingMode; - if (!hiddenForCheckboxTag.Attributes.ContainsKey("name") && - !string.IsNullOrEmpty(Name)) + // hiddenForCheckboxTag always rendered after the returned element + var hiddenForCheckboxTag = Generator.GenerateHiddenForCheckbox(ViewContext, modelExplorer, For.Name); + if (hiddenForCheckboxTag != null) { - // The checkbox and hidden elements should have the same name attribute value. Attributes will - // match if both are present because both have a generated value. Reach here in the special case - // where user provided a non-empty fallback name. - hiddenForCheckboxTag.MergeAttribute("name", Name); - } + var renderingMode = + output.TagMode == TagMode.SelfClosing ? TagRenderMode.SelfClosing : TagRenderMode.StartTag; + hiddenForCheckboxTag.TagRenderMode = renderingMode; + if (!hiddenForCheckboxTag.Attributes.ContainsKey("name") && + !string.IsNullOrEmpty(Name)) + { + // The checkbox and hidden elements should have the same name attribute value. Attributes will + // match if both are present because both have a generated value. Reach here in the special case + // where user provided a non-empty fallback name. + hiddenForCheckboxTag.MergeAttribute("name", Name); + } - if (ViewContext.FormContext.CanRenderAtEndOfForm) - { - ViewContext.FormContext.EndOfFormContent.Add(hiddenForCheckboxTag); - } - else - { - output.PostElement.AppendHtml(hiddenForCheckboxTag); + if (ViewContext.CheckBoxHiddenInputRenderMode == CheckBoxHiddenInputRenderMode.EndOfForm && ViewContext.FormContext.CanRenderAtEndOfForm) + { + ViewContext.FormContext.EndOfFormContent.Add(hiddenForCheckboxTag); + } + else + { + output.PostElement.AppendHtml(hiddenForCheckboxTag); + } } } diff --git a/src/Mvc/Mvc.TagHelpers/src/TagHelperOutputExtensions.cs b/src/Mvc/Mvc.TagHelpers/src/TagHelperOutputExtensions.cs index eb34746701..09d73843f5 100644 --- a/src/Mvc/Mvc.TagHelpers/src/TagHelperOutputExtensions.cs +++ b/src/Mvc/Mvc.TagHelpers/src/TagHelperOutputExtensions.cs @@ -277,7 +277,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers listOfClasses.RemoveAll(x => x.Equals(encodedClassValue)); - if (listOfClasses.Any()) + if (listOfClasses.Count > 0) { var joinedClasses = new HtmlString(string.Join(" ", listOfClasses)); tagHelperOutput.Attributes.SetAttribute(classAttribute.Name, joinedClasses); @@ -428,4 +428,4 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers } } } -} \ No newline at end of file +} diff --git a/src/Mvc/Mvc.TagHelpers/test/InputTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/InputTagHelperTest.cs index 265ecde1f0..557454892b 100644 --- a/src/Mvc/Mvc.TagHelpers/test/InputTagHelperTest.cs +++ b/src/Mvc/Mvc.TagHelpers/test/InputTagHelperTest.cs @@ -838,6 +838,243 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers Assert.Equal(expectedTagName, output.TagName); } + [Fact] + public async Task ProcessAsync_GenerateCheckBox_WithHiddenInputRenderModeNone() + { + var propertyName = "-expression-"; + var expectedTagName = "input"; + var inputTypeName = "checkbox"; + var expectedAttributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + { "value", "true" }, + }; + + var metadataProvider = new EmptyModelMetadataProvider(); + var htmlGenerator = new TestableHtmlGenerator(metadataProvider); + var model = false; + var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(bool), model); + var modelExpression = new ModelExpression(name: string.Empty, modelExplorer: modelExplorer); + var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); + + viewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.None; + + var tagHelper = new InputTagHelper(htmlGenerator) + { + For = modelExpression, + InputTypeName = inputTypeName, + Name = propertyName, + ViewContext = viewContext, + }; + + var attributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + }; + + var context = new TagHelperContext(attributes, new Dictionary(), "test"); + var output = new TagHelperOutput( + expectedTagName, + new TagHelperAttributeList(), + getChildContentAsync: (useCachedResult, encoder) => Task.FromResult(result: null)) + { + TagMode = TagMode.SelfClosing, + }; + + // Act + await tagHelper.ProcessAsync(context, output); + + // Assert + Assert.Equal(expectedAttributes, output.Attributes); + Assert.False(output.IsContentModified); + Assert.Equal(expectedTagName, output.TagName); + + Assert.False(viewContext.FormContext.HasEndOfFormContent); + Assert.True(string.IsNullOrEmpty(HtmlContentUtilities.HtmlContentToString(output.PostElement))); + } + + [Fact] + public async Task ProcessAsync_GenerateCheckBox_WithHiddenInputRenderModeInline() + { + var propertyName = "-expression-"; + var expectedTagName = "input"; + var expectedPostElementContent = $""; + var inputTypeName = "checkbox"; + var expectedAttributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + { "value", "true" }, + }; + + var metadataProvider = new EmptyModelMetadataProvider(); + var htmlGenerator = new TestableHtmlGenerator(metadataProvider); + var model = false; + var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(bool), model); + var modelExpression = new ModelExpression(name: string.Empty, modelExplorer: modelExplorer); + var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); + + viewContext.FormContext.CanRenderAtEndOfForm = true; + viewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.Inline; + + var tagHelper = new InputTagHelper(htmlGenerator) + { + For = modelExpression, + InputTypeName = inputTypeName, + Name = propertyName, + ViewContext = viewContext, + }; + + var attributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + }; + + var context = new TagHelperContext(attributes, new Dictionary(), "test"); + var output = new TagHelperOutput( + expectedTagName, + new TagHelperAttributeList(), + getChildContentAsync: (useCachedResult, encoder) => Task.FromResult(result: null)) + { + TagMode = TagMode.SelfClosing, + }; + + // Act + await tagHelper.ProcessAsync(context, output); + + // Assert + Assert.Equal(expectedAttributes, output.Attributes); + Assert.False(output.IsContentModified); + Assert.Equal(expectedTagName, output.TagName); + + Assert.False(viewContext.FormContext.HasEndOfFormContent); + Assert.Equal(expectedPostElementContent, HtmlContentUtilities.HtmlContentToString(output.PostElement)); + } + + [Fact] + public async Task ProcessAsync_GenerateCheckBox_WithHiddenInputRenderModeEndOfForm() + { + var propertyName = "-expression-"; + var expectedTagName = "input"; + var expectedEndOfFormContent = $""; + var inputTypeName = "checkbox"; + var expectedAttributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + { "value", "true" }, + }; + + var metadataProvider = new EmptyModelMetadataProvider(); + var htmlGenerator = new TestableHtmlGenerator(metadataProvider); + var model = false; + var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(bool), model); + var modelExpression = new ModelExpression(name: string.Empty, modelExplorer: modelExplorer); + var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); + + viewContext.FormContext.CanRenderAtEndOfForm = true; + viewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.EndOfForm; + + var tagHelper = new InputTagHelper(htmlGenerator) + { + For = modelExpression, + InputTypeName = inputTypeName, + Name = propertyName, + ViewContext = viewContext, + }; + + var attributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + }; + + var context = new TagHelperContext(attributes, new Dictionary(), "test"); + var output = new TagHelperOutput( + expectedTagName, + new TagHelperAttributeList(), + getChildContentAsync: (useCachedResult, encoder) => Task.FromResult(result: null)) + { + TagMode = TagMode.SelfClosing, + }; + + // Act + await tagHelper.ProcessAsync(context, output); + + // Assert + Assert.Equal(expectedAttributes, output.Attributes); + Assert.False(output.IsContentModified); + Assert.Equal(expectedTagName, output.TagName); + + Assert.Equal(expectedEndOfFormContent, string.Join("", viewContext.FormContext.EndOfFormContent.Select(html => HtmlContentUtilities.HtmlContentToString(html)))); + Assert.True(string.IsNullOrEmpty(HtmlContentUtilities.HtmlContentToString(output.PostElement))); + } + + [Fact] + public async Task ProcessAsync_GenerateCheckBox_WithHiddenInputRenderModeEndOfForm_AndCanRenderAtEndOfFormNotSet() + { + var propertyName = "-expression-"; + var expectedTagName = "input"; + var expectedPostElementContent = $""; + var inputTypeName = "checkbox"; + var expectedAttributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + { "value", "true" }, + }; + + var metadataProvider = new EmptyModelMetadataProvider(); + var htmlGenerator = new TestableHtmlGenerator(metadataProvider); + var model = false; + var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(bool), model); + var modelExpression = new ModelExpression(name: string.Empty, modelExplorer: modelExplorer); + var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); + + viewContext.FormContext.CanRenderAtEndOfForm = false; + viewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.EndOfForm; + + var tagHelper = new InputTagHelper(htmlGenerator) + { + For = modelExpression, + InputTypeName = inputTypeName, + Name = propertyName, + ViewContext = viewContext, + }; + + var attributes = new TagHelperAttributeList + { + { "name", propertyName }, + { "type", inputTypeName }, + }; + + var context = new TagHelperContext(attributes, new Dictionary(), "test"); + var output = new TagHelperOutput( + expectedTagName, + new TagHelperAttributeList(), + getChildContentAsync: (useCachedResult, encoder) => Task.FromResult(result: null)) + { + TagMode = TagMode.SelfClosing, + }; + + // Act + await tagHelper.ProcessAsync(context, output); + + // Assert + Assert.Equal(expectedAttributes, output.Attributes); + Assert.False(output.IsContentModified); + Assert.Equal(expectedTagName, output.TagName); + + Assert.False(viewContext.FormContext.HasEndOfFormContent); + Assert.Equal(expectedPostElementContent, HtmlContentUtilities.HtmlContentToString(output.PostElement)); + } + [Fact] public async Task ProcessAsync_CallsGenerateCheckBox_WithExpectedParameters() { diff --git a/src/Mvc/Mvc.Testing/ref/Microsoft.AspNetCore.Mvc.Testing.netcoreapp.cs b/src/Mvc/Mvc.Testing/ref/Microsoft.AspNetCore.Mvc.Testing.netcoreapp.cs index 069eae8180..4efc53b002 100644 --- a/src/Mvc/Mvc.Testing/ref/Microsoft.AspNetCore.Mvc.Testing.netcoreapp.cs +++ b/src/Mvc/Mvc.Testing/ref/Microsoft.AspNetCore.Mvc.Testing.netcoreapp.cs @@ -6,24 +6,24 @@ namespace Microsoft.AspNetCore.Mvc.Testing public partial class WebApplicationFactoryClientOptions { public WebApplicationFactoryClientOptions() { } - public bool AllowAutoRedirect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Uri BaseAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HandleCookies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int MaxAutomaticRedirections { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowAutoRedirect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Uri BaseAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HandleCookies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int MaxAutomaticRedirections { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, Inherited=false, AllowMultiple=true)] public sealed partial class WebApplicationFactoryContentRootAttribute : System.Attribute { public WebApplicationFactoryContentRootAttribute(string key, string contentRootPath, string contentRootTest, string priority) { } - public string ContentRootPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ContentRootTest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Priority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ContentRootPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ContentRootTest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Priority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class WebApplicationFactory : System.IDisposable where TEntryPoint : class { public WebApplicationFactory() { } - public Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactoryClientOptions ClientOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactoryClientOptions ClientOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IReadOnlyList> Factories { get { throw null; } } public Microsoft.AspNetCore.TestHost.TestServer Server { get { throw null; } } public virtual System.IServiceProvider Services { get { throw null; } } @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.Testing.Handlers { public CookieContainerHandler() { } public CookieContainerHandler(System.Net.CookieContainer cookieContainer) { } - public System.Net.CookieContainer Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Net.CookieContainer Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] protected override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; } } @@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Mvc.Testing.Handlers { public RedirectHandler() { } public RedirectHandler(int maxRedirects) { } - public int MaxRedirects { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int MaxRedirects { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] protected override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { throw null; } } diff --git a/src/Mvc/Mvc.Testing/src/WebApplicationFactoryContentRootAttribute.cs b/src/Mvc/Mvc.Testing/src/WebApplicationFactoryContentRootAttribute.cs index 51832bd7a8..19faf8d7f1 100644 --- a/src/Mvc/Mvc.Testing/src/WebApplicationFactoryContentRootAttribute.cs +++ b/src/Mvc/Mvc.Testing/src/WebApplicationFactoryContentRootAttribute.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Mvc.Testing /// is equal to TEntryPoint , /// order them by in ascending order. /// will check for the existence of the marker - /// in Path.Combine(, Path.GetFileName())" + /// in Path.Combine(, Path.GetFileName())" /// and if the file exists it will set the content root to . /// [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)] @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Mvc.Testing /// /// The path to the content root. This path can be either relative or absolute. /// In case the path is relative, the path will be combined with - /// + /// /// /// A file that will be use as a marker to determine that the content root path for the given context is correct. /// diff --git a/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs b/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs index dfbd0dec1b..62cfeb38a0 100644 --- a/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs +++ b/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Mvc { public AutoValidateAntiforgeryTokenAttribute() { } public bool IsReusable { get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } public abstract partial class Controller : Microsoft.AspNetCore.Mvc.ControllerBase, Microsoft.AspNetCore.Mvc.Filters.IActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, System.IDisposable @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Mvc public partial class IgnoreAntiforgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy { public IgnoreAntiforgeryTokenAttribute() { } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface IViewComponentHelper { @@ -79,9 +79,9 @@ namespace Microsoft.AspNetCore.Mvc public partial class MvcViewOptions : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable { public MvcViewOptions() { } - public System.Collections.Generic.IList ClientModelValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ClientModelValidatorProviders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelperOptions HtmlHelperOptions { get { throw null; } set { } } - public System.Collections.Generic.IList ViewEngines { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ViewEngines { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } @@ -89,20 +89,20 @@ namespace Microsoft.AspNetCore.Mvc public partial class PageRemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase { public PageRemoteAttribute() { } - public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string PageName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string PageHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string PageName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override string GetUrl(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientModelValidationContext context) { throw null; } } public partial class PartialViewResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult { public PartialViewResult() { } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public object Model { get { throw null; } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] @@ -112,7 +112,7 @@ namespace Microsoft.AspNetCore.Mvc public RemoteAttribute(string routeName) { } public RemoteAttribute(string action, string controller) { } public RemoteAttribute(string action, string controller, string areaName) { } - protected string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + protected string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected override string GetUrl(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientModelValidationContext context) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=true)] @@ -120,8 +120,8 @@ namespace Microsoft.AspNetCore.Mvc { protected RemoteAttributeBase() { } public string AdditionalFields { get { throw null; } set { } } - public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.AspNetCore.Routing.RouteValueDictionary RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string HttpMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.AspNetCore.Routing.RouteValueDictionary RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual void AddValidation(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientModelValidationContext context) { } public string FormatAdditionalFieldsForClientValidation(string property) { throw null; } public override string FormatErrorMessage(string name) { throw null; } @@ -140,14 +140,14 @@ namespace Microsoft.AspNetCore.Mvc public sealed partial class TempDataAttribute : System.Attribute { public TempDataAttribute() { } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public partial class ValidateAntiForgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public ValidateAntiForgeryTokenAttribute() { } public bool IsReusable { get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } [Microsoft.AspNetCore.Mvc.ViewComponentAttribute] @@ -178,37 +178,37 @@ namespace Microsoft.AspNetCore.Mvc public partial class ViewComponentAttribute : System.Attribute { public ViewComponentAttribute() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ViewComponentResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult { public ViewComponentResult() { } - public object Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public object Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public object Model { get { throw null; } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ViewComponentName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type ViewComponentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ViewComponentName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type ViewComponentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, Inherited=true, AllowMultiple=false)] public sealed partial class ViewDataAttribute : System.Attribute { public ViewDataAttribute() { } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ViewResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.AspNetCore.Mvc.IActionResult, Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult { public ViewResult() { } - public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ContentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public object Model { get { throw null; } } - public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) { throw null; } } @@ -219,12 +219,12 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics { public const string EventName = "Microsoft.AspNetCore.Mvc.AfterViewComponent"; public AfterViewComponentEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext viewComponentContext, Microsoft.AspNetCore.Mvc.IViewComponentResult viewComponentResult, object viewComponent) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public object ViewComponent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.IViewComponentResult ViewComponentResult { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object ViewComponent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.IViewComponentResult ViewComponentResult { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class AfterViewEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { @@ -232,18 +232,18 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics public AfterViewEventData(Microsoft.AspNetCore.Mvc.ViewEngines.IView view, Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext) { } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeViewComponentEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.BeforeViewComponent"; public BeforeViewComponentEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext viewComponentContext, object viewComponent) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public object ViewComponent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object ViewComponent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class BeforeViewEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { @@ -251,52 +251,52 @@ namespace Microsoft.AspNetCore.Mvc.Diagnostics public BeforeViewEventData(Microsoft.AspNetCore.Mvc.ViewEngines.IView view, Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext) { } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class ViewComponentAfterViewExecuteEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.ViewComponentAfterViewExecute"; public ViewComponentAfterViewExecuteEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext viewComponentContext, Microsoft.AspNetCore.Mvc.ViewEngines.IView view) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class ViewComponentBeforeViewExecuteEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.ViewComponentBeforeViewExecute"; public ViewComponentBeforeViewExecuteEventData(Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor actionDescriptor, Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext viewComponentContext, Microsoft.AspNetCore.Mvc.ViewEngines.IView view) { } - public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor ActionDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext ViewComponentContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class ViewFoundEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.ViewFound"; public ViewFoundEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, bool isMainPage, Microsoft.AspNetCore.Mvc.ActionResult result, string viewName, Microsoft.AspNetCore.Mvc.ViewEngines.IView view) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public bool IsMainPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsMainPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public sealed partial class ViewNotFoundEventData : Microsoft.AspNetCore.Mvc.Diagnostics.EventData { public const string EventName = "Microsoft.AspNetCore.Mvc.ViewNotFound"; public ViewNotFoundEventData(Microsoft.AspNetCore.Mvc.ActionContext actionContext, bool isMainPage, Microsoft.AspNetCore.Mvc.ActionResult result, string viewName, System.Collections.Generic.IEnumerable searchedLocations) { } - public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionContext ActionContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override int Count { get { throw null; } } - public bool IsMainPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool IsMainPage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Collections.Generic.KeyValuePair this[int index] { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IEnumerable SearchedLocations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ActionResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IEnumerable SearchedLocations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.ModelBinding @@ -312,6 +312,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding } namespace Microsoft.AspNetCore.Mvc.Rendering { + public enum CheckBoxHiddenInputRenderMode + { + None = 0, + Inline = 1, + EndOfForm = 2, + } public enum FormMethod { Get = 0, @@ -595,11 +601,11 @@ namespace Microsoft.AspNetCore.Mvc.Rendering public MultiSelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField) { } public MultiSelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField, System.Collections.IEnumerable selectedValues) { } public MultiSelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField, System.Collections.IEnumerable selectedValues, string dataGroupField) { } - public string DataGroupField { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string DataTextField { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string DataValueField { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.IEnumerable Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.IEnumerable SelectedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string DataGroupField { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string DataTextField { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string DataValueField { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.IEnumerable Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.IEnumerable SelectedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual System.Collections.Generic.IEnumerator GetEnumerator() { throw null; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } } @@ -623,13 +629,13 @@ namespace Microsoft.AspNetCore.Mvc.Rendering public SelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField) : base (default(System.Collections.IEnumerable)) { } public SelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField, object selectedValue) : base (default(System.Collections.IEnumerable)) { } public SelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField, object selectedValue, string dataGroupField) : base (default(System.Collections.IEnumerable)) { } - public object SelectedValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object SelectedValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class SelectListGroup { public SelectListGroup() { } - public bool Disabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Disabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SelectListItem { @@ -637,11 +643,11 @@ namespace Microsoft.AspNetCore.Mvc.Rendering public SelectListItem(string text, string value) { } public SelectListItem(string text, string value, bool selected) { } public SelectListItem(string text, string value, bool selected, bool disabled) { } - public bool Disabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Rendering.SelectListGroup Group { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Selected { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Text { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Disabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Rendering.SelectListGroup Group { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Selected { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Text { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString()}")] public partial class TagBuilder : Microsoft.AspNetCore.Html.IHtmlContent @@ -650,8 +656,8 @@ namespace Microsoft.AspNetCore.Mvc.Rendering public Microsoft.AspNetCore.Mvc.ViewFeatures.AttributeDictionary Attributes { get { throw null; } } public bool HasInnerHtml { get { throw null; } } public Microsoft.AspNetCore.Html.IHtmlContentBuilder InnerHtml { get { throw null; } } - public string TagName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.Rendering.TagRenderMode TagRenderMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string TagName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.Rendering.TagRenderMode TagRenderMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void AddCssClass(string value) { } public static string CreateSanitizedId(string name, string invalidCharReplacement) { throw null; } public void GenerateId(string name, string invalidCharReplacement) { } @@ -684,17 +690,18 @@ namespace Microsoft.AspNetCore.Mvc.Rendering public ViewContext() { } public ViewContext(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ViewEngines.IView view, Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary viewData, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary tempData, System.IO.TextWriter writer, Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelperOptions htmlHelperOptions) { } public ViewContext(Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, Microsoft.AspNetCore.Mvc.ViewEngines.IView view, Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary viewData, System.IO.TextWriter writer) { } - public bool ClientValidationEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ExecutingFilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.CheckBoxHiddenInputRenderMode CheckBoxHiddenInputRenderMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ClientValidationEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ExecutingFilePath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual Microsoft.AspNetCore.Mvc.ViewFeatures.FormContext FormContext { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.Rendering.Html5DateRenderingMode Html5DateRenderingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ValidationMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ValidationSummaryMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.Html5DateRenderingMode Html5DateRenderingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ValidationMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ValidationSummaryMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public dynamic ViewBag { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.IO.TextWriter Writer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.IO.TextWriter Writer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.ViewFeatures.FormContext GetFormContextForClientValidation() { throw null; } } } @@ -703,7 +710,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents public partial class ContentViewComponentResult : Microsoft.AspNetCore.Mvc.IViewComponentResult { public ContentViewComponentResult(string content) { } - public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Content { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Execute(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext context) { } public System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext context) { throw null; } } @@ -739,7 +746,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents public partial class HtmlContentViewComponentResult : Microsoft.AspNetCore.Mvc.IViewComponentResult { public HtmlContentViewComponentResult(Microsoft.AspNetCore.Html.IHtmlContent encodedContent) { } - public Microsoft.AspNetCore.Html.IHtmlContent EncodedContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Html.IHtmlContent EncodedContent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Execute(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext context) { } public System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext context) { throw null; } } @@ -783,11 +790,11 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents { public ViewComponentContext() { } public ViewComponentContext(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentDescriptor viewComponentDescriptor, System.Collections.Generic.IDictionary arguments, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, System.IO.TextWriter writer) { } - public System.Collections.Generic.IDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentDescriptor ViewComponentDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentDescriptor ViewComponentDescriptor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get { throw null; } } public System.IO.TextWriter Writer { get { throw null; } } } @@ -808,23 +815,23 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents { public ViewComponentDescriptor() { } public string DisplayName { get { throw null; } set { } } - public string FullName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IReadOnlyList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ShortName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Reflection.TypeInfo TypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string FullName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.MethodInfo MethodInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IReadOnlyList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ShortName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Reflection.TypeInfo TypeInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ViewComponentDescriptorCollection { public ViewComponentDescriptorCollection(System.Collections.Generic.IEnumerable items, int version) { } - public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ViewComponentFeature { public ViewComponentFeature() { } - public System.Collections.Generic.IList ViewComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IList ViewComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ViewComponentFeatureProvider : Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationFeatureProvider, Microsoft.AspNetCore.Mvc.ApplicationParts.IApplicationFeatureProvider { @@ -834,10 +841,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents public partial class ViewViewComponentResult : Microsoft.AspNetCore.Mvc.IViewComponentResult { public ViewViewComponentResult() { } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Execute(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext context) { } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentContext context) { throw null; } @@ -848,7 +855,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewEngines public partial class CompositeViewEngine : Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine, Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine { public CompositeViewEngine(Microsoft.Extensions.Options.IOptions optionsAccessor) { } - public System.Collections.Generic.IReadOnlyList ViewEngines { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList ViewEngines { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult FindView(Microsoft.AspNetCore.Mvc.ActionContext context, string viewName, bool isMainPage) { throw null; } public Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult GetView(string executingFilePath, string viewPath, bool isMainPage) { throw null; } } @@ -869,10 +876,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewEngines public partial class ViewEngineResult { internal ViewEngineResult() { } - public System.Collections.Generic.IEnumerable SearchedLocations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable SearchedLocations { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool Success { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewEngines.IView View { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ViewName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult EnsureSuccessful(System.Collections.Generic.IEnumerable originalLocations) { throw null; } public static Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult Found(string viewName, Microsoft.AspNetCore.Mvc.ViewEngines.IView view) { throw null; } public static Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult NotFound(string viewName, System.Collections.Generic.IEnumerable searchedLocations) { throw null; } @@ -929,8 +936,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public partial class DefaultHtmlGenerator : Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator { public DefaultHtmlGenerator(Microsoft.AspNetCore.Antiforgery.IAntiforgery antiforgery, Microsoft.Extensions.Options.IOptions optionsAccessor, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory urlHelperFactory, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, Microsoft.AspNetCore.Mvc.ViewFeatures.ValidationHtmlAttributeProvider validationAttributeProvider) { } - protected bool AllowRenderingMaxLengthAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string IdAttributeDotReplacement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected bool AllowRenderingMaxLengthAttribute { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string IdAttributeDotReplacement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected virtual void AddMaxLengthAttribute(Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary viewData, Microsoft.AspNetCore.Mvc.Rendering.TagBuilder tagBuilder, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer modelExplorer, string expression) { } protected virtual void AddPlaceholderAttribute(Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary viewData, Microsoft.AspNetCore.Mvc.Rendering.TagBuilder tagBuilder, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer modelExplorer, string expression) { } protected virtual void AddValidationAttributes(Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, Microsoft.AspNetCore.Mvc.Rendering.TagBuilder tagBuilder, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer modelExplorer, string expression) { } @@ -975,10 +982,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public partial class FormContext { public FormContext() { } - public bool CanRenderAtEndOfForm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool CanRenderAtEndOfForm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.IList EndOfFormContent { get { throw null; } } public System.Collections.Generic.IDictionary FormData { get { throw null; } } - public bool HasAntiforgeryToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool HasAntiforgeryToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public bool HasEndOfFormContent { get { throw null; } } public bool HasFormData { get { throw null; } } public bool RenderedField(string fieldName) { throw null; } @@ -995,9 +1002,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public HtmlHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator htmlGenerator, Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.IViewBufferScope bufferScope, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, System.Text.Encodings.Web.UrlEncoder urlEncoder) { } public Microsoft.AspNetCore.Mvc.Rendering.Html5DateRenderingMode Html5DateRenderingMode { get { throw null; } set { } } public string IdAttributeDotReplacement { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary TempData { get { throw null; } } - public System.Text.Encodings.Web.UrlEncoder UrlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Text.Encodings.Web.UrlEncoder UrlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public dynamic ViewBag { get { throw null; } } public Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get { throw null; } } public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get { throw null; } } @@ -1068,16 +1075,17 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public partial class HtmlHelperOptions { public HtmlHelperOptions() { } - public bool ClientValidationEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Mvc.Rendering.Html5DateRenderingMode Html5DateRenderingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.Rendering.CheckBoxHiddenInputRenderMode CheckBoxHiddenInputRenderMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ClientValidationEnabled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Mvc.Rendering.Html5DateRenderingMode Html5DateRenderingMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string IdAttributeDotReplacement { get { throw null; } set { } } - public string ValidationMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ValidationSummaryMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ValidationMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ValidationSummaryMessageElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HtmlHelper : Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper, Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper, Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper { public HtmlHelper(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator htmlGenerator, Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.IViewBufferScope bufferScope, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, System.Text.Encodings.Web.UrlEncoder urlEncoder, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpressionProvider modelExpressionProvider) : base (default(Microsoft.AspNetCore.Mvc.ViewFeatures.IHtmlGenerator), default(Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine), default(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider), default(Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.IViewBufferScope), default(System.Text.Encodings.Web.HtmlEncoder), default(System.Text.Encodings.Web.UrlEncoder)) { } - public new Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public new Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Html.IHtmlContent CheckBoxFor(System.Linq.Expressions.Expression> expression, object htmlAttributes) { throw null; } public override void Contextualize(Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext) { } public Microsoft.AspNetCore.Html.IHtmlContent DisplayFor(System.Linq.Expressions.Expression> expression, string templateName, string htmlFieldName, object additionalViewData) { throw null; } @@ -1174,8 +1182,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public ModelExplorer(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, object model) { } public ModelExplorer(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer container, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, System.Func modelAccessor) { } public ModelExplorer(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider metadataProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer container, Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata metadata, object model) { } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public object Model { get { throw null; } } public System.Type ModelType { get { throw null; } } public System.Collections.Generic.IEnumerable Properties { get { throw null; } } @@ -1197,8 +1205,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public ModelExpression(string name, Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer modelExplorer) { } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata Metadata { get { throw null; } } public object Model { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer ModelExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer ModelExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class ModelExpressionProvider : Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider { @@ -1214,7 +1222,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public partial class PartialViewResultExecutor : Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor, Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor { public PartialViewResultExecutor(Microsoft.Extensions.Options.IOptions viewOptions, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory tempDataFactory, System.Diagnostics.DiagnosticListener diagnosticListener, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider modelMetadataProvider) : base (default(Microsoft.Extensions.Options.IOptions), default(Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory), default(Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine), default(Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory), default(System.Diagnostics.DiagnosticListener), default(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider)) { } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext context, Microsoft.AspNetCore.Mvc.PartialViewResult result) { throw null; } public virtual System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ViewEngines.IView view, Microsoft.AspNetCore.Mvc.PartialViewResult viewResult) { throw null; } @@ -1225,7 +1233,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures { public SaveTempDataAttribute() { } public bool IsReusable { get { throw null; } } - public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) { throw null; } } public partial class SessionStateTempDataProvider : Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataProvider @@ -1319,10 +1327,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public object this[string index] { get { throw null; } set { } } public System.Collections.Generic.ICollection Keys { get { throw null; } } public object Model { get { throw null; } set { } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer ModelExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer ModelExplorer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata ModelMetadata { get { throw null; } } - public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Mvc.ViewFeatures.TemplateInfo TemplateInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Mvc.ViewFeatures.TemplateInfo TemplateInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.ICollection Values { get { throw null; } } public void Add(System.Collections.Generic.KeyValuePair item) { } public void Add(string key, object value) { } @@ -1369,8 +1377,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public ViewDataInfo(object container, object value) { } public ViewDataInfo(object container, System.Reflection.PropertyInfo propertyInfo) { } public ViewDataInfo(object container, System.Reflection.PropertyInfo propertyInfo, System.Func valueAccessor) { } - public object Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Container { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public object Value { get { throw null; } set { } } } public partial class ViewExecutor @@ -1378,12 +1386,12 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public static readonly string DefaultContentType; protected ViewExecutor(Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, System.Diagnostics.DiagnosticListener diagnosticListener) { } public ViewExecutor(Microsoft.Extensions.Options.IOptions viewOptions, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory tempDataFactory, System.Diagnostics.DiagnosticListener diagnosticListener, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider modelMetadataProvider) { } - protected System.Diagnostics.DiagnosticListener DiagnosticListener { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider ModelMetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory TempDataFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.MvcViewOptions ViewOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory WriterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected System.Diagnostics.DiagnosticListener DiagnosticListener { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider ModelMetadataProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory TempDataFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.MvcViewOptions ViewOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory WriterFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public virtual System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ViewEngines.IView view, Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary viewData, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionary tempData, string contentType, int? statusCode) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -1392,7 +1400,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures public partial class ViewResultExecutor : Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor, Microsoft.AspNetCore.Mvc.Infrastructure.IActionResultExecutor { public ViewResultExecutor(Microsoft.Extensions.Options.IOptions viewOptions, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory, Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine viewEngine, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory tempDataFactory, System.Diagnostics.DiagnosticListener diagnosticListener, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider modelMetadataProvider) : base (default(Microsoft.Extensions.Options.IOptions), default(Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory), default(Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine), default(Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory), default(System.Diagnostics.DiagnosticListener), default(Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider)) { } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext context, Microsoft.AspNetCore.Mvc.ViewResult result) { throw null; } public virtual Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult FindView(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.ViewResult viewResult) { throw null; } @@ -1411,9 +1419,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers public readonly partial struct ViewBufferValue { private readonly object _dummy; + private readonly int _dummyPrimitive; public ViewBufferValue(Microsoft.AspNetCore.Html.IHtmlContent content) { throw null; } public ViewBufferValue(string value) { throw null; } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Infrastructure diff --git a/src/Mvc/Mvc.ViewFeatures/src/DefaultHtmlGenerator.cs b/src/Mvc/Mvc.ViewFeatures/src/DefaultHtmlGenerator.cs index d546c59e4e..4169b94cba 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/DefaultHtmlGenerator.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/DefaultHtmlGenerator.cs @@ -12,6 +12,7 @@ using System.Reflection; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Html; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Routing; @@ -307,7 +308,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures { defaultMethod = true; } - else if (string.Equals(method, "post", StringComparison.OrdinalIgnoreCase)) + else if (HttpMethods.IsPost(method)) { defaultMethod = true; } diff --git a/src/Mvc/Mvc.ViewFeatures/src/Filters/AutoValidateAntiforgeryTokenAuthorizationFilter.cs b/src/Mvc/Mvc.ViewFeatures/src/Filters/AutoValidateAntiforgeryTokenAuthorizationFilter.cs index 032fa98ec6..80cbd6b3f6 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Filters/AutoValidateAntiforgeryTokenAuthorizationFilter.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Filters/AutoValidateAntiforgeryTokenAuthorizationFilter.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNetCore.Antiforgery; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; @@ -23,10 +24,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Filters } var method = context.HttpContext.Request.Method; - if (string.Equals("GET", method, StringComparison.OrdinalIgnoreCase) || - string.Equals("HEAD", method, StringComparison.OrdinalIgnoreCase) || - string.Equals("TRACE", method, StringComparison.OrdinalIgnoreCase) || - string.Equals("OPTIONS", method, StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsGet(method) || + HttpMethods.IsHead(method) || + HttpMethods.IsTrace(method) || + HttpMethods.IsOptions(method)) { return false; } diff --git a/src/Mvc/Mvc.ViewFeatures/src/HtmlHelper.cs b/src/Mvc/Mvc.ViewFeatures/src/HtmlHelper.cs index 016246f4a4..cf8ee07fd9 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/HtmlHelper.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/HtmlHelper.cs @@ -721,8 +721,18 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures isChecked, htmlAttributes); + if (checkbox == null) + { + return HtmlString.Empty; + } + + if (ViewContext.CheckBoxHiddenInputRenderMode == CheckBoxHiddenInputRenderMode.None) + { + return checkbox; + } + var hiddenForCheckbox = _htmlGenerator.GenerateHiddenForCheckbox(ViewContext, modelExplorer, expression); - if (checkbox == null || hiddenForCheckbox == null) + if (hiddenForCheckbox == null) { return HtmlString.Empty; } @@ -736,7 +746,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures hiddenForCheckbox.MergeAttribute("name", name); } - if (ViewContext.FormContext.CanRenderAtEndOfForm) + if (ViewContext.CheckBoxHiddenInputRenderMode == CheckBoxHiddenInputRenderMode.EndOfForm && ViewContext.FormContext.CanRenderAtEndOfForm) { ViewContext.FormContext.EndOfFormContent.Add(hiddenForCheckbox); return checkbox; diff --git a/src/Mvc/Mvc.ViewFeatures/src/HtmlHelperOptions.cs b/src/Mvc/Mvc.ViewFeatures/src/HtmlHelperOptions.cs index 952bc7b4d9..f40bdf93f6 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/HtmlHelperOptions.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/HtmlHelperOptions.cs @@ -56,5 +56,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures /// and other overloads. /// public string ValidationSummaryMessageElement { get; set; } = "span"; + + /// + /// Gets or sets the way hidden inputs are rendered for checkbox tag helpers and html helpers. + /// + public CheckBoxHiddenInputRenderMode CheckBoxHiddenInputRenderMode { get; set; } = CheckBoxHiddenInputRenderMode.EndOfForm; } } diff --git a/src/Mvc/Mvc.ViewFeatures/src/IHtmlGenerator.cs b/src/Mvc/Mvc.ViewFeatures/src/IHtmlGenerator.cs index f0f59d4ba2..fb6859087d 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/IHtmlGenerator.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/IHtmlGenerator.cs @@ -216,6 +216,21 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures string method, object htmlAttributes); + /// + /// Generate a <input type="hidden"> element + /// + /// A instance for the current scope. + /// The for the . + /// Expression name, relative to the current model. + /// The value which is injected into the element + /// Whether to use the ViewData to generate this element + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GenerateHidden( ViewContext viewContext, ModelExplorer modelExplorer, @@ -224,6 +239,20 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures bool useViewData, object htmlAttributes); + /// + /// Generate a <label> element + /// + /// A instance for the current scope. + /// The for the . + /// Expression name, relative to the current model. Used to set the target of the label. + /// Text used to render this label. + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GenerateLabel( ViewContext viewContext, ModelExplorer modelExplorer, @@ -231,6 +260,20 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures string labelText, object htmlAttributes); + /// + /// Generate a <input type="password"> element + /// + /// A instance for the current scope. + /// The for the . + /// Expression name, relative to the current model. + /// Value used to prefill the checkbox + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GeneratePassword( ViewContext viewContext, ModelExplorer modelExplorer, @@ -238,6 +281,21 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures object value, object htmlAttributes); + /// + /// Generate a <input type="radio"> element + /// + /// A instance for the current scope. + /// The for the . + /// Expression name, relative to the current model. + /// value of the given radio button + /// Whether or not the radio button is checked + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GenerateRadioButton( ViewContext viewContext, ModelExplorer modelExplorer, @@ -384,6 +442,21 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures /// IHtmlContent GenerateGroupsAndOptions(string optionLabel, IEnumerable selectList); + /// + /// Generates a <textarea> element + /// + /// A instance for the current scope. + /// The for the . + /// Expression name, relative to the current model. + /// + /// + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GenerateTextArea( ViewContext viewContext, ModelExplorer modelExplorer, @@ -392,6 +465,21 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures int columns, object htmlAttributes); + /// + /// Generates a <input type="text"> element + /// + /// A instance for the current scope. + /// The for the . + /// Expression name, relative to the current model. + /// + /// + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GenerateTextBox( ViewContext viewContext, ModelExplorer modelExplorer, @@ -420,12 +508,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures /// An that contains the HTML attributes for the element. Alternatively, an /// instance containing the HTML attributes. /// - /// - /// A containing a element if the - /// 's contains an error for the - /// or (as a placeholder) if client-side validation is enabled. null if - /// the is valid and client-side validation is disabled. - /// + /// /// is "span" by default. TagBuilder GenerateValidationMessage( ViewContext viewContext, @@ -435,6 +518,20 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures string tag, object htmlAttributes); + /// + /// Generates a <div> element which contains a list of validation errors. + /// + /// + /// + /// + /// + /// + /// An that contains the parameters for a route. The parameters are retrieved through + /// reflection by examining the properties of the . This is typically + /// created using initializer syntax. Alternatively, an + /// instance containing the route parameters. + /// + /// TagBuilder GenerateValidationSummary( ViewContext viewContext, bool excludePropertyErrors, diff --git a/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/StaticComponentRenderer.cs b/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/StaticComponentRenderer.cs index 89304873c1..411e6014a8 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/StaticComponentRenderer.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/RazorComponents/StaticComponentRenderer.cs @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures // all components have rendered. throw new InvalidOperationException("A navigation command was attempted during prerendering after the server already started sending the response. " + "Navigation commands can not be issued during server-side prerendering after the response from the server has started. Applications must buffer the" + - "reponse and avoid using features like FlushAsync() before all components on the page have been rendered to prevent failed navigation commands.", navigationException); + "response and avoid using features like FlushAsync() before all components on the page have been rendered to prevent failed navigation commands.", navigationException); } httpContext.Response.Redirect(navigationException.Location); diff --git a/src/Mvc/Mvc.ViewFeatures/src/Rendering/CheckBoxHiddenInputRenderMode.cs b/src/Mvc/Mvc.ViewFeatures/src/Rendering/CheckBoxHiddenInputRenderMode.cs new file mode 100644 index 0000000000..3d89c44d80 --- /dev/null +++ b/src/Mvc/Mvc.ViewFeatures/src/Rendering/CheckBoxHiddenInputRenderMode.cs @@ -0,0 +1,27 @@ +// 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. + +namespace Microsoft.AspNetCore.Mvc.Rendering +{ + /// + /// Controls the rendering of hidden input fields when using CheckBox tag helpers or html helpers. + /// + public enum CheckBoxHiddenInputRenderMode + { + /// + /// Hidden input fields will not be automatically rendered. If checkbox is not checked, no value will be posted. + /// + None = 0, + + /// + /// Hidden input fields will be rendered inline with each checkbox. Use this for legacy ASP.NET MVC behavior. + /// + Inline = 1, + + /// + /// Hidden input fields will be rendered for each checkbox at the bottom of the form element. This is the preferred render method and default MVC behavior. + /// If is false, will fall back on . + /// + EndOfForm = 2 + } +} diff --git a/src/Mvc/Mvc.ViewFeatures/src/Rendering/MultiSelectList.cs b/src/Mvc/Mvc.ViewFeatures/src/Rendering/MultiSelectList.cs index 360b75b87e..f9205363a2 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Rendering/MultiSelectList.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Rendering/MultiSelectList.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering { /// /// Represents a list that lets users select multiple items. - /// This class is typically rendered as an HTML <select multiple="multiple"> element with the specified collection + /// This class is typically rendered as an HTML <select multiple="multiple"> element with the specified collection /// of objects. /// public class MultiSelectList : IEnumerable diff --git a/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectList.cs b/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectList.cs index 7d30bffeb7..69649326c8 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectList.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectList.cs @@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering { /// /// Represents a list that lets users select a single item. - /// This class is typically rendered as an HTML <select> element with the specified collection + /// This class is typically rendered as an HTML <select> element with the specified collection /// of objects. /// public class SelectList : MultiSelectList diff --git a/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectListItem.cs b/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectListItem.cs index 4a3efe43fb..4735b973c8 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectListItem.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Rendering/SelectListItem.cs @@ -5,7 +5,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering { /// /// Represents an item in a or . - /// This class is typically rendered as an HTML <option> element with the specified + /// This class is typically rendered as an HTML <option> element with the specified /// attribute values. /// public class SelectListItem @@ -54,8 +54,8 @@ namespace Microsoft.AspNetCore.Mvc.Rendering /// /// Gets or sets a value that indicates whether this is disabled. - /// This property is typically rendered as a disabled="disabled" attribute in the HTML - /// <option> element. + /// This property is typically rendered as a disabled="disabled" attribute in the HTML + /// <option> element. /// public bool Disabled { get; set; } @@ -68,21 +68,21 @@ namespace Microsoft.AspNetCore.Mvc.Rendering /// /// Gets or sets a value that indicates whether this is selected. - /// This property is typically rendered as a selected="selected" attribute in the HTML - /// <option> element. + /// This property is typically rendered as a selected="selected" attribute in the HTML + /// <option> element. /// public bool Selected { get; set; } /// /// Gets or sets a value that indicates the display text of this . - /// This property is typically rendered as the inner HTML in the HTML <option> element. + /// This property is typically rendered as the inner HTML in the HTML <option> element. /// public string Text { get; set; } /// /// Gets or sets a value that indicates the value of this . - /// This property is typically rendered as a value="..." attribute in the HTML - /// <option> element. + /// This property is typically rendered as a value="..." attribute in the HTML + /// <option> element. /// public string Value { get; set; } } diff --git a/src/Mvc/Mvc.ViewFeatures/src/Rendering/ViewContext.cs b/src/Mvc/Mvc.ViewFeatures/src/Rendering/ViewContext.cs index 0604cfc26e..ac2d6c48c9 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/Rendering/ViewContext.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/Rendering/ViewContext.cs @@ -89,6 +89,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering Html5DateRenderingMode = htmlHelperOptions.Html5DateRenderingMode; ValidationSummaryMessageElement = htmlHelperOptions.ValidationSummaryMessageElement; ValidationMessageElement = htmlHelperOptions.ValidationMessageElement; + CheckBoxHiddenInputRenderMode = htmlHelperOptions.CheckBoxHiddenInputRenderMode; } /// @@ -131,6 +132,8 @@ namespace Microsoft.AspNetCore.Mvc.Rendering Html5DateRenderingMode = viewContext.Html5DateRenderingMode; ValidationSummaryMessageElement = viewContext.ValidationSummaryMessageElement; ValidationMessageElement = viewContext.ValidationMessageElement; + CheckBoxHiddenInputRenderMode = viewContext.CheckBoxHiddenInputRenderMode; + ExecutingFilePath = viewContext.ExecutingFilePath; View = view; ViewData = viewData; @@ -184,6 +187,11 @@ namespace Microsoft.AspNetCore.Mvc.Rendering /// public string ValidationMessageElement { get; set; } + /// + /// Gets or sets the way hidden inputs are rendered for checkbox tag helpers and html helpers. + /// + public CheckBoxHiddenInputRenderMode CheckBoxHiddenInputRenderMode { get; set; } + /// /// Gets the dynamic view bag. /// diff --git a/src/Mvc/Mvc.ViewFeatures/src/ViewComponents/ViewComponentDescriptor.cs b/src/Mvc/Mvc.ViewFeatures/src/ViewComponents/ViewComponentDescriptor.cs index 4aa1125757..cc7578de77 100644 --- a/src/Mvc/Mvc.ViewFeatures/src/ViewComponents/ViewComponentDescriptor.cs +++ b/src/Mvc/Mvc.ViewFeatures/src/ViewComponents/ViewComponentDescriptor.cs @@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents /// /// The full name is defaulted to the full namespace of the view component class, prepended to /// the class name with a '.' character as the separator. If the view component class uses - /// ViewComponent as a suffix, the suffix will be omitted from the . + /// ViewComponent as a suffix, the suffix will be omitted from the . /// /// /// Class Name: Contoso.Products.LoginViewComponent @@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents /// /// /// The short name is defaulted to the name of the view component class. If the view component class uses - /// ViewComponent as a suffix, the suffix will be omitted from the . + /// ViewComponent as a suffix, the suffix will be omitted from the . /// /// /// Class Name: Contoso.Products.LoginViewComponent diff --git a/src/Mvc/Mvc.ViewFeatures/test/RazorComponents/ComponentRendererTest.cs b/src/Mvc/Mvc.ViewFeatures/test/RazorComponents/ComponentRendererTest.cs index 1e89472473..f9e403ca2f 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/RazorComponents/ComponentRendererTest.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/RazorComponents/ComponentRendererTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -473,8 +473,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures })); Assert.Equal("A navigation command was attempted during prerendering after the server already started sending the response. " + - "Navigation commands can not be issued during server-side prerendering after the response from the server has started. Applications must buffer the" + - "reponse and avoid using features like FlushAsync() before all components on the page have been rendered to prevent failed navigation commands.", + "Navigation commands can not be issued during server-side prerendering after the response from the server has started. Applications must buffer the" + + "response and avoid using features like FlushAsync() before all components on the page have been rendered to prevent failed navigation commands.", exception.Message); } diff --git a/src/Mvc/Mvc.ViewFeatures/test/Rendering/HtmlHelperCheckboxTest.cs b/src/Mvc/Mvc.ViewFeatures/test/Rendering/HtmlHelperCheckboxTest.cs index 67cfb7f64e..ab35762255 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/Rendering/HtmlHelperCheckboxTest.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/Rendering/HtmlHelperCheckboxTest.cs @@ -169,6 +169,93 @@ namespace Microsoft.AspNetCore.Mvc.Rendering writer.ToString()); } + [Fact] + public void CheckBox_WithHiddenInputRenderModeNone_DoesNotGenerateHiddenInput() + { + // Arrange + var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("Boolean"); + var expected = @""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetTestModelViewData()); + helper.ViewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.None; + + // Act + var html = helper.CheckBox("Property1", isChecked: true, htmlAttributes: null); + + // Assert + Assert.False(helper.ViewContext.FormContext.HasEndOfFormContent); + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(html)); + } + + [Fact] + public void CheckBox_WithHiddenInputRenderModeInline_GeneratesHiddenInput() + { + // Arrange + var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("Boolean"); + var expected = @""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetTestModelViewData()); + helper.ViewContext.FormContext.CanRenderAtEndOfForm = true; + helper.ViewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.Inline; + + // Act + var html = helper.CheckBox("Property1", isChecked: true, htmlAttributes: null); + + // Assert + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(html)); + } + + [Fact] + public void CheckBox_WithHiddenInputRenderModeEndOfForm_GeneratesHiddenInput() + { + // Arrange + var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("Boolean"); + var expected = @""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetTestModelViewData()); + helper.ViewContext.FormContext.CanRenderAtEndOfForm = true; + helper.ViewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.EndOfForm; + + // Act + var html = helper.CheckBox("Property1", isChecked: true, htmlAttributes: null); + + // Assert + Assert.True(helper.ViewContext.FormContext.HasEndOfFormContent); + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(html)); + var writer = new StringWriter(); + var hiddenTag = Assert.Single(helper.ViewContext.FormContext.EndOfFormContent); + hiddenTag.WriteTo(writer, new HtmlTestEncoder()); + Assert.Equal("", + writer.ToString()); + } + + [Fact] + public void CheckBox_WithHiddenInputRenderModeEndOfForm_WithCanRenderAtEndOfFormNotSet_GeneratesHiddenInput() + { + // Arrange + var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("Boolean"); + var expected = @""; + var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetTestModelViewData()); + helper.ViewContext.FormContext.CanRenderAtEndOfForm = false; + helper.ViewContext.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.EndOfForm; + + // Act + var html = helper.CheckBox("Property1", isChecked: true, htmlAttributes: null); + + // Assert + Assert.False(helper.ViewContext.FormContext.HasEndOfFormContent); + Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(html)); + } + [Fact] public void CheckBoxUsesAttemptedValueFromModelState() { diff --git a/src/Mvc/Mvc.ViewFeatures/test/TempDataDictionaryTest.cs b/src/Mvc/Mvc.ViewFeatures/test/TempDataDictionaryTest.cs index b9c1b6c813..f8cf0d5a60 100644 --- a/src/Mvc/Mvc.ViewFeatures/test/TempDataDictionaryTest.cs +++ b/src/Mvc/Mvc.ViewFeatures/test/TempDataDictionaryTest.cs @@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures Assert.Same(item, value); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/17102")] public void TempData_LoadAndSaveAreCaseInsensitive() { // Arrange @@ -163,7 +163,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures Assert.True(tempData.ContainsKey("bar")); } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/17102")] public void TempData_RemovalOfKeysAreCaseInsensitive() { var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider()); diff --git a/src/Mvc/Mvc.sln b/src/Mvc/Mvc.sln index e848546fbb..8bf09cc810 100644 --- a/src/Mvc/Mvc.sln +++ b/src/Mvc/Mvc.sln @@ -309,6 +309,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Signal EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Metadata", "..\Http\Metadata\src\Microsoft.AspNetCore.Metadata.csproj", "{464195B3-022A-4D19-9104-8C66CC882D67}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.Authorization", "..\Components\Authorization\src\Microsoft.AspNetCore.Components.Authorization.csproj", "{23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.Forms", "..\Components\Forms\src\Microsoft.AspNetCore.Components.Forms.csproj", "{1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DataProtection.Extensions", "..\DataProtection\Extensions\src\Microsoft.AspNetCore.DataProtection.Extensions.csproj", "{96613225-4637-45C1-A161-5CE4C9B085A2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1765,6 +1771,42 @@ Global {464195B3-022A-4D19-9104-8C66CC882D67}.Release|Mixed Platforms.Build.0 = Release|Any CPU {464195B3-022A-4D19-9104-8C66CC882D67}.Release|x86.ActiveCfg = Release|Any CPU {464195B3-022A-4D19-9104-8C66CC882D67}.Release|x86.Build.0 = Release|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Debug|x86.ActiveCfg = Debug|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Debug|x86.Build.0 = Debug|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Release|Any CPU.Build.0 = Release|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Release|x86.ActiveCfg = Release|Any CPU + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6}.Release|x86.Build.0 = Release|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Debug|x86.ActiveCfg = Debug|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Debug|x86.Build.0 = Debug|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Release|Any CPU.Build.0 = Release|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Release|x86.ActiveCfg = Release|Any CPU + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB}.Release|x86.Build.0 = Release|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Debug|x86.ActiveCfg = Debug|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Debug|x86.Build.0 = Debug|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Release|Any CPU.Build.0 = Release|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Release|x86.ActiveCfg = Release|Any CPU + {96613225-4637-45C1-A161-5CE4C9B085A2}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1893,6 +1935,9 @@ Global {A8C3066F-E80D-4E03-9962-741B551B8FBC} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C} {637119E8-5BBB-4FC7-A372-DAF38FF5EBD9} = {5FE3048A-E96B-44F8-A7C4-FC590D7E04B4} {464195B3-022A-4D19-9104-8C66CC882D67} = {5FE3048A-E96B-44F8-A7C4-FC590D7E04B4} + {23D69471-8ED8-4D2D-B44D-6F1E41FF48D6} = {5FE3048A-E96B-44F8-A7C4-FC590D7E04B4} + {1AD53D5B-8F91-44C0-BDF9-5DDEB37354EB} = {5FE3048A-E96B-44F8-A7C4-FC590D7E04B4} + {96613225-4637-45C1-A161-5CE4C9B085A2} = {5FE3048A-E96B-44F8-A7C4-FC590D7E04B4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {63D344F6-F86D-40E6-85B9-0AABBE338C4A} diff --git a/src/Mvc/benchmarkapps/BasicApi/benchmarks.json b/src/Mvc/benchmarkapps/BasicApi/benchmarks.json index 29c1506bb6..26a9d998c8 100644 --- a/src/Mvc/benchmarkapps/BasicApi/benchmarks.json +++ b/src/Mvc/benchmarkapps/BasicApi/benchmarks.json @@ -7,7 +7,7 @@ "PresetHeaders": "Json", "ReadyStateText": "Application started.", "Source": { - "Repository": "https://github.com/aspnet/AspNetCore.git", + "Repository": "https://github.com/dotnet/aspnetcore.git", "BranchOrCommit": "master", "Project": "src/Mvc/benchmarkapps/BasicApi/BasicApi.csproj" } @@ -19,20 +19,20 @@ }, "BasicApi.GetUsingQueryString": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicApi/getWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicApi/getWithToken.lua" }, "Path": "/pet/findByStatus", "Query": "?status=available" }, "BasicApi.GetUsingRouteValue": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicApi/getWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicApi/getWithToken.lua" }, "Path": "/pet/-1" }, "BasicApi.GetUsingRouteValueWithoutAuthorization": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicApi/getWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicApi/getWithToken.lua" }, "Path": "/pet/anonymous/-1" }, @@ -41,14 +41,14 @@ }, "BasicApi.Post": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicApi/postJsonWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicApi/postJsonWithToken.lua" }, "Path": "/pet" }, "BasicApi.PostWithoutDb": { "Path": "/pet/add-pet", "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicApi/postJsonWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicApi/postJsonWithToken.lua" } } } diff --git a/src/Mvc/benchmarkapps/BasicViews/benchmarks.json b/src/Mvc/benchmarkapps/BasicViews/benchmarks.json index 20990be77a..96fd8cd0bc 100644 --- a/src/Mvc/benchmarkapps/BasicViews/benchmarks.json +++ b/src/Mvc/benchmarkapps/BasicViews/benchmarks.json @@ -7,7 +7,7 @@ "PresetHeaders": "Html", "ReadyStateText": "Application started.", "Source": { - "Repository": "https://github.com/aspnet/AspNetCore.git", + "Repository": "https://github.com/dotnet/aspnetcore.git", "BranchOrCommit": "master", "Project": "src/Mvc/benchmarkapps/BasicViews/BasicViews.csproj" } @@ -20,19 +20,19 @@ }, "BasicViews.Post": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicViews/postWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicViews/postWithToken.lua" }, "Path": "/Home/Index" }, "BasicViews.PostIgnoringToken": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicViews/postWithToken.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicViews/postWithToken.lua" }, "Path": "/Home/IndexWithoutToken" }, "BasicViews.PostWithoutToken": { "ClientProperties": { - "Scripts": "https://raw.githubusercontent.com/aspnet/AspNetCore/master/src/Mvc/benchmarkapps/BasicViews/post.lua" + "Scripts": "https://raw.githubusercontent.com/dotnet/aspnetcore/master/src/Mvc/benchmarkapps/BasicViews/post.lua" }, "Path": "/Home/IndexWithoutToken" } diff --git a/src/Mvc/test/Mvc.FunctionalTests/Infrastructure/ResourceFile.cs b/src/Mvc/test/Mvc.FunctionalTests/Infrastructure/ResourceFile.cs index 013847e683..dea4cf6aac 100644 --- a/src/Mvc/test/Mvc.FunctionalTests/Infrastructure/ResourceFile.cs +++ b/src/Mvc/test/Mvc.FunctionalTests/Infrastructure/ResourceFile.cs @@ -192,7 +192,7 @@ namespace Microsoft.AspNetCore.Mvc // The build system compiles every file under the resources folder as a resource available at runtime // with the same name as the file name. Need to update this file on disc. -// https://github.com/aspnet/AspNetCore/issues/10423 +// https://github.com/dotnet/aspnetcore/issues/10423 #pragma warning disable 0618 var solutionPath = TestPathUtilities.GetSolutionRootDirectory("Mvc"); #pragma warning restore 0618 diff --git a/src/Mvc/test/Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj b/src/Mvc/test/Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj index 70385d88d5..13df24aab5 100644 --- a/src/Mvc/test/Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj +++ b/src/Mvc/test/Mvc.FunctionalTests/Microsoft.AspNetCore.Mvc.FunctionalTests.csproj @@ -9,7 +9,7 @@ Mvc.FunctionalTests false - + false diff --git a/src/Mvc/test/Mvc.FunctionalTests/RoutingDynamicTest.cs b/src/Mvc/test/Mvc.FunctionalTests/RoutingDynamicTest.cs index bd306b7bbf..da6392f9fc 100644 --- a/src/Mvc/test/Mvc.FunctionalTests/RoutingDynamicTest.cs +++ b/src/Mvc/test/Mvc.FunctionalTests/RoutingDynamicTest.cs @@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests [Fact] public async Task AppWithDynamicRouteAndMapRazorPages_CanRouteToRazorPage() { - // Regression test for https://github.com/aspnet/AspNetCore/issues/13996 + // Regression test for https://github.com/dotnet/aspnetcore/issues/13996 // Arrange var client = Factory.WithWebHostBuilder(b => b.UseStartup()).CreateDefaultClient(); var url = "/PageWithLinks"; @@ -123,7 +123,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests [Fact] public async Task AppWithDynamicRouteAndMapRazorPages_CanRouteToDynamicController() { - // Regression test for https://github.com/aspnet/AspNetCore/issues/13996 + // Regression test for https://github.com/dotnet/aspnetcore/issues/13996 // Arrange var client = Factory.WithWebHostBuilder(b => b.UseStartup()).CreateDefaultClient(); var url = "/de/area%3Dadmin,controller%3Ddynamic,action%3Dindex"; diff --git a/src/Mvc/test/Mvc.FunctionalTests/TagHelpersTest.cs b/src/Mvc/test/Mvc.FunctionalTests/TagHelpersTest.cs index 420f3af313..8f8adcefba 100644 --- a/src/Mvc/test/Mvc.FunctionalTests/TagHelpersTest.cs +++ b/src/Mvc/test/Mvc.FunctionalTests/TagHelpersTest.cs @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests [Fact] public async Task GivesCorrectCallstackForSyncronousCalls() { - // Regression test for https://github.com/aspnet/AspNetCore/issues/15367 + // Regression test for https://github.com/dotnet/aspnetcore/issues/15367 // Arrange var exception = await Assert.ThrowsAsync(async () => await Client.GetAsync("http://localhost/Home/MyHtml")); diff --git a/src/Mvc/test/Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs b/src/Mvc/test/Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs index 34a0e4fca8..3377b9ce8f 100644 --- a/src/Mvc/test/Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs +++ b/src/Mvc/test/Mvc.IntegrationTests/CollectionModelBinderIntegrationTest.cs @@ -1129,7 +1129,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests [Fact] public async Task CollectionModelBinder_CollectionOfSimpleTypes_DoesNotResultInValidationError() { - // Regression test for https://github.com/aspnet/AspNetCore/issues/13512 + // Regression test for https://github.com/dotnet/aspnetcore/issues/13512 // Arrange var parameter = new ParameterDescriptor() { diff --git a/src/Mvc/test/Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs b/src/Mvc/test/Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs index bb9949c422..473926154d 100644 --- a/src/Mvc/test/Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs +++ b/src/Mvc/test/Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs @@ -1830,7 +1830,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests Assert.Equal("10", entry.RawValue); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11813")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/11813")] public async Task MutableObjectModelBinder_BindsKeyValuePairProperty_NoCollectionData() { // Arrange @@ -1879,7 +1879,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests Assert.Single(entry.Errors); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11813")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/11813")] public async Task MutableObjectModelBinder_BindsKeyValuePairProperty_NoData() { // Arrange diff --git a/src/Mvc/test/Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs b/src/Mvc/test/Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs index 5bdcafa6c5..0920e94d29 100644 --- a/src/Mvc/test/Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs +++ b/src/Mvc/test/Mvc.IntegrationTests/DictionaryModelBinderIntegrationTest.cs @@ -1166,7 +1166,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests [Fact] public async Task DictionaryModelBinder_DictionaryOfSimpleType_NullValue_DoesNotResultInRequiredValidation() { - // Regression test for https://github.com/aspnet/AspNetCore/issues/13512 + // Regression test for https://github.com/dotnet/aspnetcore/issues/13512 // Arrange var parameterBinder = ModelBindingTestHelper.GetParameterBinder(); var parameter = new ParameterDescriptor() diff --git a/src/Mvc/test/Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs b/src/Mvc/test/Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs index e33ca1923c..f8da065e39 100644 --- a/src/Mvc/test/Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs +++ b/src/Mvc/test/Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs @@ -311,7 +311,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests Assert.Equal("10", entry.RawValue); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11813")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/11813")] public async Task KeyValuePairModelBinder_BindsKeyValuePairOfSimpleType_NoData() { // Arrange @@ -476,7 +476,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests Assert.Equal("10", entry.RawValue); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/11813")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/11813")] public async Task KeyValuePairModelBinder_BindsKeyValuePairOfComplexType_NoData() { // Arrange diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json index b6cb64fcec..3297878253 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/template.json @@ -85,12 +85,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "HostIdentifier": { "type": "bind", diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json index 5cb50d10a5..5372ab65cb 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/.template.config/vs-2017.3.host.json @@ -11,7 +11,7 @@ }, "order": 610, "icon": "icon.png", - "learnMoreLink": "https://github.com/aspnet/AspNetCore", + "learnMoreLink": "https://github.com/dotnet/aspnetcore", "uiFilters": [ "oneaspnet" ], diff --git a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html index 7c402d8073..675d440c23 100644 --- a/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html +++ b/src/ProjectTemplates/BlazorWasm.ProjectTemplates/content/BlazorWasm-CSharp/Client/wwwroot/index.html @@ -1,6 +1,5 @@ - - + @@ -18,7 +17,7 @@ Reload 🗙 + - diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json index 12fe72720c..8a669b652a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/.template.config/template.json @@ -337,12 +337,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/wwwroot/css/site.css b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/wwwroot/css/site.css index c15c2e1556..f875d35edb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/wwwroot/css/site.css +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorServerWeb-CSharp/wwwroot/css/site.css @@ -129,12 +129,12 @@ app { z-index: 1000; } -#blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; -} + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } @media (max-width: 767.98px) { .main .top-row:not(.auth) { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json index 96ac0383be..08c6bb56c8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-CSharp/.template.config/template.json @@ -86,12 +86,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-FSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-FSharp/.template.config/template.json index 1102d7952d..7c9eb6c777 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-FSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/EmptyWeb-FSharp/.template.config/template.json @@ -82,12 +82,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json index ff8ed336b0..0b8a573d28 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/GrpcService-CSharp/.template.config/template.json @@ -41,11 +41,11 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "defaultValue": "netcoreapp3.1" + "defaultValue": "netcoreapp5.0" }, "ExcludeLaunchSettings": { "type": "parameter", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorClassLibrary-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorClassLibrary-CSharp/.template.config/template.json index 1b4166341a..86a7607fa2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorClassLibrary-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorClassLibrary-CSharp/.template.config/template.json @@ -4,8 +4,7 @@ "classifications": [ "Web", "Razor", - "Library", - "Razor Class Library" + "Library" ], "name": "Razor Class Library", "generatorVersions": "[1.0.0.0-*)", @@ -48,11 +47,11 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "defaultValue": "netcoreapp3.1" + "defaultValue": "netcoreapp5.0" }, "HostIdentifier": { "type": "bind", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json index 5a01244a34..90e8b01562 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/.template.config/template.json @@ -310,12 +310,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml index ccc07b30f6..835d806c2e 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/Pages/Shared/_Layout.cshtml @@ -50,6 +50,6 @@ - @RenderSection("Scripts", required: false) + @await RenderSectionAsync("Scripts", required: false) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/js/site.js b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/js/site.js index 3c76e6dc45..ac49c18641 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/js/site.js +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/RazorPagesWeb-CSharp/wwwroot/js/site.js @@ -1,4 +1,4 @@ // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification // for details on configuring this project to bundle and minify static web assets. -// Write your Javascript code. +// Write your JavaScript code. diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json index d01fcbf4f0..7f4d444645 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/.template.config/template.json @@ -300,12 +300,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Views/Shared/_Layout.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Views/Shared/_Layout.cshtml index 892d6b9b5d..5234625f8d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Views/Shared/_Layout.cshtml +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-CSharp/Views/Shared/_Layout.cshtml @@ -48,6 +48,6 @@ - @RenderSection("Scripts", required: false) + @await RenderSectionAsync("Scripts", required: false) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/.template.config/template.json index 5ac6316167..487cdfc527 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/.template.config/template.json @@ -87,12 +87,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/Views/Shared/_Layout.cshtml b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/Views/Shared/_Layout.cshtml index 6dbe6964a7..b326cdff07 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/Views/Shared/_Layout.cshtml +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/Views/Shared/_Layout.cshtml @@ -47,6 +47,6 @@ - @RenderSection("Scripts", required: false) + @await RenderSectionAsync("Scripts", required: false) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/js/site.js b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/js/site.js index 3c76e6dc45..ac49c18641 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/js/site.js +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/StarterWeb-FSharp/wwwroot/js/site.js @@ -1,4 +1,4 @@ // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification // for details on configuring this project to bundle and minify static web assets. -// Write your Javascript code. +// Write your JavaScript code. diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json index b0facf26da..2de35fc292 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-CSharp/.template.config/template.json @@ -209,12 +209,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-FSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-FSharp/.template.config/template.json index 514e77d41b..e1639b58b9 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-FSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/WebApi-FSharp/.template.config/template.json @@ -82,12 +82,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json index 1e9cc2414b..16156aef0d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/Worker-CSharp/.template.config/template.json @@ -47,12 +47,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "copyrightYear": { "type": "generated", diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/.template.config/template.json index 07b982ad9e..f0162aa616 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/.template.config/template.json @@ -177,12 +177,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "HostIdentifier": { "type": "bind", diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/api-authorization/authorize.service.ts b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/api-authorization/authorize.service.ts index cf6e33cfda..779eb24850 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/api-authorization/authorize.service.ts +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/api-authorization/authorize.service.ts @@ -135,7 +135,7 @@ export class AuthorizeService { await this.userManager.signoutRedirect(this.createArguments(state)); return this.redirect(); } catch (redirectSignOutError) { - console.log('Redirect signout error: ', popupSignOutError); + console.log('Redirect signout error: ', redirectSignOutError); return this.error(redirectSignOutError); } } diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/app.module.ts b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/app.module.ts index f66fa53203..679b31ce33 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/app.module.ts +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/app.module.ts @@ -1,7 +1,11 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; +////#if (IndividualLocalAuth) import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; +////#else +import { HttpClientModule } from '@angular/common/http'; +////#endif import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/counter/counter.component.spec.ts b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/counter/counter.component.spec.ts index 026a91a062..37b350cc1c 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/counter/counter.component.spec.ts +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/app/counter/counter.component.spec.ts @@ -3,7 +3,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { CounterComponent } from './counter.component'; describe('CounterComponent', () => { - let component: CounterComponent; let fixture: ComponentFixture; beforeEach(async(() => { @@ -15,7 +14,6 @@ describe('CounterComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(CounterComponent); - component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/test.ts b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/test.ts index 16317897b1..88492582fb 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/test.ts +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/src/test.ts @@ -7,7 +7,7 @@ import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -declare const require: any; +declare const require; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Controllers/OidcConfigurationController.cs b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Controllers/OidcConfigurationController.cs index 75e26da4e9..cdcc89182a 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Controllers/OidcConfigurationController.cs +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Controllers/OidcConfigurationController.cs @@ -6,12 +6,12 @@ namespace Company.WebApplication1.Controllers { public class OidcConfigurationController : Controller { - private readonly ILogger logger; + private readonly ILogger _logger; - public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider, ILogger _logger) + public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider, ILogger logger) { ClientRequestParametersProvider = clientRequestParametersProvider; - logger = _logger; + _logger = logger; } public IClientRequestParametersProvider ClientRequestParametersProvider { get; } diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/.template.config/template.json index c6e9544e43..6490d8e061 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/.template.config/template.json @@ -178,12 +178,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "HostIdentifier": { "type": "bind", diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/.env b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/.env new file mode 100644 index 0000000000..6ce384e5ce --- /dev/null +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/.env @@ -0,0 +1 @@ +BROWSER=none diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/src/components/api-authorization/Login.js b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/src/components/api-authorization/Login.js index 7ef201c91c..3954657f30 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/src/components/api-authorization/Login.js +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/React-CSharp/ClientApp/src/components/api-authorization/Login.js @@ -120,7 +120,7 @@ export class Login extends Component { redirectToApiAuthorizationPath(apiAuthorizationPath) { const redirectUrl = `${window.location.origin}${apiAuthorizationPath}`; // It's important that we do a replace here so that when the user hits the back arrow on the - // browser he gets sent back to where it was on the app instead of to an endpoint on this + // browser they get sent back to where it was on the app instead of to an endpoint on this // component. window.location.replace(redirectUrl); } diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/.template.config/template.json index 9c7ce60528..0f2945d10f 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/.template.config/template.json +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/.template.config/template.json @@ -87,12 +87,12 @@ "datatype": "choice", "choices": [ { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" + "choice": "netcoreapp5.0", + "description": "Target netcoreapp5.0" } ], - "replaces": "netcoreapp3.1", - "defaultValue": "netcoreapp3.1" + "replaces": "netcoreapp5.0", + "defaultValue": "netcoreapp5.0" }, "HostIdentifier": { "type": "bind", diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.env b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.env new file mode 100644 index 0000000000..6ce384e5ce --- /dev/null +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.env @@ -0,0 +1 @@ +BROWSER=none diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.eslintrc.json b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.eslintrc.json index f5e132e0e2..40fe7d79bc 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.eslintrc.json +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/.eslintrc.json @@ -3,5 +3,8 @@ "parserOptions": { "ecmaVersion": 6, "sourceType": "module" - } + }, + "plugins": [ + "@typescript-eslint" + ] } \ No newline at end of file diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/FetchData.tsx b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/FetchData.tsx index 9fed830288..a0c1b7a1e5 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/FetchData.tsx +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/FetchData.tsx @@ -81,4 +81,4 @@ class FetchData extends React.PureComponent { export default connect( (state: ApplicationState) => state.weatherForecasts, // Selects which state properties are merged into the component's props WeatherForecastsStore.actionCreators // Selects which action creators are merged into the component's props -)(FetchData as any); +)(FetchData as any); // eslint-disable-line @typescript-eslint/no-explicit-any diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Home.tsx b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Home.tsx index 5f7d5ff661..d452be0ee3 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Home.tsx +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Home.tsx @@ -10,7 +10,7 @@ const Home = () => (
  • React and Redux for client-side code
  • Bootstrap for layout and styling
  • -

    To help you get started, we've also set up:

    +

    To help you get started, we have also set up:

    • Client-side navigation. For example, click Counter then Back to return here.
    • Development server integration. In development mode, the development server from create-react-app runs in the background automatically, so your client-side resources are dynamically built on demand and the page refreshes when you modify any file.
    • diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Layout.tsx b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Layout.tsx index 80ddb46adb..766c65df0f 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Layout.tsx +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/components/Layout.tsx @@ -2,11 +2,15 @@ import * as React from 'react'; import { Container } from 'reactstrap'; import NavMenu from './NavMenu'; -export default (props: { children?: React.ReactNode }) => ( - - - - {props.children} - - -); +export default class Layout extends React.PureComponent<{}, { children?: React.ReactNode }> { + public render() { + return ( + + + + {this.props.children} + + + ); + } +} \ No newline at end of file diff --git a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/store/configureStore.ts b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/store/configureStore.ts index 68c74c589d..89bb95258c 100644 --- a/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/store/configureStore.ts +++ b/src/ProjectTemplates/Web.Spa.ProjectTemplates/content/ReactRedux-CSharp/ClientApp/src/store/configureStore.ts @@ -16,7 +16,7 @@ export default function configureStore(history: History, initialState?: Applicat }); const enhancers = []; - const windowIfDefined = typeof window === 'undefined' ? null : window as any; + const windowIfDefined = typeof window === 'undefined' ? null : window as any; // eslint-disable-line @typescript-eslint/no-explicit-any if (windowIfDefined && windowIfDefined.__REDUX_DEVTOOLS_EXTENSION__) { enhancers.push(windowIfDefined.__REDUX_DEVTOOLS_EXTENSION__()); } diff --git a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 index ba4180de95..ec8993da7e 100644 --- a/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-Angular-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.3.1.3.1.0-dev.nupkg" $true +Test-Template "angular" "angular" "Microsoft.DotNet.Web.Spa.ProjectTemplates.5.0.5.0.0-dev.nupkg" $true diff --git a/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 index 7d989b65a3..575036e9c7 100644 --- a/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-Blazor-Locally.ps1 @@ -10,4 +10,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "blazorserver" "blazorserver" "Microsoft.DotNet.Web.ProjectTemplates.3.1.3.1.0-dev.nupkg" $false +Test-Template "blazorserver" "blazorserver" "Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 b/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 index 6aeffd7687..d6859c6f72 100644 --- a/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-EmptyWeb-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "web" "web" "Microsoft.DotNet.Web.ProjectTemplates.3.1.3.1.0-dev.nupkg" $false +Test-Template "web" "web" "Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 index f77838b435..ecba4fbd8f 100644 --- a/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-Razor-Locally.ps1 @@ -6,4 +6,4 @@ param() . $PSScriptRoot\Test-Template.ps1 -Test-Template "webapp" "webapp -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.3.1.3.1.0-dev.nupkg" $false +Test-Template "webapp" "webapp -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-React-Locally.ps1 b/src/ProjectTemplates/scripts/Run-React-Locally.ps1 index 972bfc4ead..8308860edc 100644 --- a/src/ProjectTemplates/scripts/Run-React-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-React-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.3.1.3.1.0-dev.nupkg" $true +Test-Template "react" "react" "Microsoft.DotNet.Web.Spa.ProjectTemplates.5.0.5.0.0-dev.nupkg" $true diff --git a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 index 4c01f11400..6100d7cacd 100644 --- a/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-ReactRedux-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.3.1.3.1.0-dev.nupkg" $true +Test-Template "reactredux" "reactredux" "Microsoft.DotNet.Web.Spa.ProjectTemplates.5.0.5.0.0-dev.nupkg" $true diff --git a/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 index 7971ae01ac..61ad47fbdc 100644 --- a/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-Starterweb-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "mvc" "mvc -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.3.1.3.1.0-dev.nupkg" $false +Test-Template "mvc" "mvc -au Individual" "Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 b/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 index 94fd8d012b..e6ff856e7e 100644 --- a/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 +++ b/src/ProjectTemplates/scripts/Run-Worker-Locally.ps1 @@ -9,4 +9,4 @@ $ErrorActionPreference = 'Stop' . $PSScriptRoot\Test-Template.ps1 -Test-Template "worker" "worker" "Microsoft.DotNet.Web.ProjectTemplates.3.1.3.1.0-dev.nupkg" $false +Test-Template "worker" "worker" "Microsoft.DotNet.Web.ProjectTemplates.5.0.5.0.0-dev.nupkg" $false diff --git a/src/ProjectTemplates/scripts/Test-Template.ps1 b/src/ProjectTemplates/scripts/Test-Template.ps1 index d13b7e452c..5ad25a16d6 100644 --- a/src/ProjectTemplates/scripts/Test-Template.ps1 +++ b/src/ProjectTemplates/scripts/Test-Template.ps1 @@ -32,7 +32,7 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isSPA) { $proj = "$tmpDir/$templateName.$extension" $projContent = Get-Content -Path $proj -Raw $projContent = $projContent -replace ('', " - + @@ -42,7 +42,7 @@ function Test-Template($templateName, $templateArgs, $templateNupkg, $isSPA) { $projContent | Set-Content $proj dotnet.exe ef migrations add mvc dotnet.exe publish --configuration Release - dotnet.exe bin\Release\netcoreapp3.1\publish\$templateName.dll + dotnet.exe bin\Release\netcoreapp5.0\publish\$templateName.dll } finally { Pop-Location diff --git a/src/ProjectTemplates/test/BlazorServerTemplateTest.cs b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs new file mode 100644 index 0000000000..463b710ac3 --- /dev/null +++ b/src/ProjectTemplates/test/BlazorServerTemplateTest.cs @@ -0,0 +1,168 @@ +// 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.Net; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.E2ETesting; +using Microsoft.AspNetCore.Testing; +using OpenQA.Selenium; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class BlazorServerTemplateTest : BrowserTestBase + { + public BlazorServerTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) : base(browserFixture, output) + { + ProjectFactory = projectFactory; + } + + public ProjectFactoryFixture ProjectFactory { get; set; } + + public Project Project { get; private set; } + + [Fact] + public async Task BlazorServerTemplateWorks_NoAuth() + { + Project = await ProjectFactory.GetOrCreateProject("blazorservernoauth", Output); + + var createResult = await Project.RunDotNetNewAsync("blazorserver"); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); + if (BrowserFixture.IsHostAutomationSupported()) + { + aspNetProcess.VisitInBrowser(Browser); + TestBasicNavigation(); + } + else + { + BrowserFixture.EnforceSupportedConfigurations(); + } + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); + if (BrowserFixture.IsHostAutomationSupported()) + { + aspNetProcess.VisitInBrowser(Browser); + TestBasicNavigation(); + } + else + { + BrowserFixture.EnforceSupportedConfigurations(); + } + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task BlazorServerTemplateWorks_IndividualAuth(bool useLocalDB) + { + Project = await ProjectFactory.GetOrCreateProject("blazorserverindividual" + (useLocalDB ? "uld" : ""), Output); + + var createResult = await Project.RunDotNetNewAsync("blazorserver", auth: "Individual", useLocalDB: useLocalDB); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); + if (BrowserFixture.IsHostAutomationSupported()) + { + aspNetProcess.VisitInBrowser(Browser); + TestBasicNavigation(); + } + else + { + BrowserFixture.EnforceSupportedConfigurations(); + } + } + + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); + if (BrowserFixture.IsHostAutomationSupported()) + { + aspNetProcess.VisitInBrowser(Browser); + TestBasicNavigation(); + } + } + } + + private void TestBasicNavigation() + { + // Give components.server enough time to load so that it can replace + // the prerendered content before we start making assertions. + Thread.Sleep(5000); + Browser.Exists(By.TagName("ul")); + // element gets project ID injected into it during template execution + Browser.Equal(Project.ProjectName.Trim(), () => Browser.Title.Trim()); + + // Initially displays the home page + Browser.Equal("Hello, world!", () => Browser.FindElement(By.TagName("h1")).Text); + + // Can navigate to the counter page + Browser.FindElement(By.PartialLinkText("Counter")).Click(); + Browser.Contains("counter", () => Browser.Url); + Browser.Equal("Counter", () => Browser.FindElement(By.TagName("h1")).Text); + + // Clicking the counter button works + Browser.Equal("Current count: 0", () => Browser.FindElement(By.CssSelector("h1 + p")).Text); + Browser.FindElement(By.CssSelector("p+button")).Click(); + Browser.Equal("Current count: 1", () => Browser.FindElement(By.CssSelector("h1 + p")).Text); + + // Can navigate to the 'fetch data' page + Browser.FindElement(By.PartialLinkText("Fetch data")).Click(); + Browser.Contains("fetchdata", () => Browser.Url); + Browser.Equal("Weather forecast", () => Browser.FindElement(By.TagName("h1")).Text); + + // Asynchronously loads and displays the table of weather forecasts + Browser.Exists(By.CssSelector("table>tbody>tr")); + Browser.Equal(5, () => Browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count); + } + } +} diff --git a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs index 41cb82ac21..0a6ea40f83 100644 --- a/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs +++ b/src/ProjectTemplates/test/BlazorWasmTemplateTest.cs @@ -24,7 +24,7 @@ namespace Templates.Test public ProjectFactoryFixture ProjectFactory { get; set; } - [Fact] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/17681")] public async Task BlazorWasmStandaloneTemplate_Works() { var project = await ProjectFactory.GetOrCreateProject("blazorstandalone", Output); diff --git a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs new file mode 100644 index 0000000000..bcd52da1d5 --- /dev/null +++ b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs @@ -0,0 +1,79 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class EmptyWebTemplateTest + { + public EmptyWebTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; } + + public ITestOutputHelper Output { get; } + + [Fact] + public async Task EmptyWebTemplateCSharp() + { + await EmtpyTemplateCore(languageOverride: null); + } + + [Fact] + public async Task EmptyWebTemplateFSharp() + { + await EmtpyTemplateCore("F#"); + } + + private async Task EmtpyTemplateCore(string languageOverride) + { + Project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); + + var createResult = await Project.RunDotNetNewAsync("web", language: languageOverride); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + // Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022 + if (languageOverride != null) + { + return; + } + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertOk("/"); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertOk("/"); + } + } + } +} diff --git a/src/ProjectTemplates/test/GrpcTemplateTest.cs b/src/ProjectTemplates/test/GrpcTemplateTest.cs new file mode 100644 index 0000000000..8d0eef0395 --- /dev/null +++ b/src/ProjectTemplates/test/GrpcTemplateTest.cs @@ -0,0 +1,89 @@ +// 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.Runtime.InteropServices; +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class GrpcTemplateTest + { + public GrpcTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; } + public ITestOutputHelper Output { get; } + + [Fact] + public async Task GrpcTemplate() + { + Project = await ProjectFactory.GetOrCreateProject("grpc", Output); + + var createResult = await Project.RunDotNetNewAsync("grpc"); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + using (var serverProcess = Project.StartBuiltProjectAsync()) + { + // These templates are HTTPS + HTTP/2 only which is not supported on Mac due to missing ALPN support. + // https://github.com/dotnet/aspnetcore/issues/11061 + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Assert.True(serverProcess.Process.HasExited, "built"); + Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on macOS due to missing ALPN support.", + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process)); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version < new Version(6, 2)) + { + Assert.True(serverProcess.Process.HasExited, "built"); + Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on Windows 7 due to missing ALPN support.", + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process)); + } + else + { + Assert.False( + serverProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process)); + } + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + // These templates are HTTPS + HTTP/2 only which is not supported on Mac due to missing ALPN support. + // https://github.com/dotnet/aspnetcore/issues/11061 + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Assert.True(aspNetProcess.Process.HasExited, "published"); + Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on macOS due to missing ALPN support.", + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process)); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version < new Version(6, 2)) + { + Assert.True(aspNetProcess.Process.HasExited, "published"); + Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on Windows 7 due to missing ALPN support.", + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process)); + } + else + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process)); + } + } + } + } +} diff --git a/src/ProjectTemplates/test/Helpers/PageUrls.cs b/src/ProjectTemplates/test/Helpers/PageUrls.cs index afb0783cbc..deb12fb16c 100644 --- a/src/ProjectTemplates/test/Helpers/PageUrls.cs +++ b/src/ProjectTemplates/test/Helpers/PageUrls.cs @@ -12,6 +12,7 @@ namespace Templates.Test.Helpers public const string LoginUrl = "/Identity/Account/Login"; public const string RegisterUrl = "/Identity/Account/Register"; public const string ForgotPassword = "/Identity/Account/ForgotPassword"; + public const string ResendEmailConfirmation = "/Identity/Account/ResendEmailConfirmation"; public const string ExternalArticle = "https://go.microsoft.com/fwlink/?LinkID=532715"; } } diff --git a/src/ProjectTemplates/test/Helpers/ProcessEx.cs b/src/ProjectTemplates/test/Helpers/ProcessEx.cs index 517c23e7a8..f5bf857996 100644 --- a/src/ProjectTemplates/test/Helpers/ProcessEx.cs +++ b/src/ProjectTemplates/test/Helpers/ProcessEx.cs @@ -164,7 +164,7 @@ namespace Templates.Test.Helpers { if (!_process.HasExited) { - throw new InvalidOperationException("Process has not finished running."); + throw new InvalidOperationException($"Process {_process.ProcessName} with pid: {_process.Id} has not finished running."); } return $"Process exited with code {_process.ExitCode}\nStdErr: {Error}\nStdOut: {Output}"; @@ -174,12 +174,16 @@ namespace Templates.Test.Helpers { if(!timeSpan.HasValue) { - timeSpan = TimeSpan.FromSeconds(480); + timeSpan = TimeSpan.FromSeconds(600); } - Exited.Wait(timeSpan.Value); - - if (assertSuccess && _process.ExitCode != 0) + var exited = Exited.Wait(timeSpan.Value); + if (!exited) + { + _output.WriteLine($"The process didn't exit within the allotted time ({timeSpan.Value.TotalSeconds} seconds)."); + _process.Dispose(); + } + else if (assertSuccess && _process.ExitCode != 0) { throw new Exception($"Process exited with code {_process.ExitCode}\nStdErr: {Error}\nStdOut: {Output}"); } diff --git a/src/ProjectTemplates/test/Helpers/Project.cs b/src/ProjectTemplates/test/Helpers/Project.cs index 19f1d46b7f..33e50d2091 100644 --- a/src/ProjectTemplates/test/Helpers/Project.cs +++ b/src/ProjectTemplates/test/Helpers/Project.cs @@ -120,7 +120,7 @@ namespace Templates.Test.Helpers await effectiveLock.WaitAsync(); try { - var result = ProcessEx.Run(Output, TemplateOutputDir, DotNetMuxer.MuxerPathOrDefault(), $"publish -c Release /bl /nr:false {additionalArgs}", packageOptions); + var result = ProcessEx.Run(Output, TemplateOutputDir, DotNetMuxer.MuxerPathOrDefault(), $"publish -c Release /bl {additionalArgs}", packageOptions); await result.Exited; CaptureBinLogOnFailure(result); return result; @@ -142,7 +142,7 @@ namespace Templates.Test.Helpers await effectiveLock.WaitAsync(); try { - var result = ProcessEx.Run(Output, TemplateOutputDir, DotNetMuxer.MuxerPathOrDefault(), $"build -c Debug /bl /nr:false {additionalArgs}", packageOptions); + var result = ProcessEx.Run(Output, TemplateOutputDir, DotNetMuxer.MuxerPathOrDefault(), $"build -c Debug /bl {additionalArgs}", packageOptions); await result.Exited; CaptureBinLogOnFailure(result); return result; @@ -210,7 +210,7 @@ namespace Templates.Test.Helpers }; var projectDll = Path.Combine(TemplateBuildDir, $"{ProjectName}.dll"); - return new AspNetProcess(Output, TemplateOutputDir, projectDll, environment, published: false, hasListeningUri: hasListeningUri); + return new AspNetProcess(Output, TemplateOutputDir, projectDll, environment, hasListeningUri: hasListeningUri); } internal AspNetProcess StartPublishedProjectAsync(bool hasListeningUri = true) @@ -241,7 +241,7 @@ namespace Templates.Test.Helpers do { restoreResult = await RestoreAsync(output, workingDirectory); - if (restoreResult.ExitCode == 0) + if (restoreResult.HasExited && restoreResult.ExitCode == 0) { return restoreResult; } diff --git a/src/ProjectTemplates/test/Helpers/TemplatePackageInstaller.cs b/src/ProjectTemplates/test/Helpers/TemplatePackageInstaller.cs index 5d6985f691..30983a55fc 100644 --- a/src/ProjectTemplates/test/Helpers/TemplatePackageInstaller.cs +++ b/src/ProjectTemplates/test/Helpers/TemplatePackageInstaller.cs @@ -32,10 +32,12 @@ namespace Templates.Test.Helpers "Microsoft.DotNet.Web.ProjectTemplates.2.2", "Microsoft.DotNet.Web.ProjectTemplates.3.0", "Microsoft.DotNet.Web.ProjectTemplates.3.1", + "Microsoft.DotNet.Web.ProjectTemplates.5.0", "Microsoft.DotNet.Web.Spa.ProjectTemplates.2.1", "Microsoft.DotNet.Web.Spa.ProjectTemplates.2.2", "Microsoft.DotNet.Web.Spa.ProjectTemplates.3.0", "Microsoft.DotNet.Web.Spa.ProjectTemplates.3.1", + "Microsoft.DotNet.Web.Spa.ProjectTemplates.5.0", "Microsoft.DotNet.Web.Spa.ProjectTemplates", "Microsoft.AspNetCore.Blazor.Templates", }; @@ -91,7 +93,7 @@ namespace Templates.Test.Helpers /* * The templates are indexed by path, for example: - &USERPROFILE%\.templateengine\dotnetcli\v3.0.100-preview7-012821\packages\nunit3.dotnetnew.template.1.6.1.nupkg + &USERPROFILE%\.templateengine\dotnetcli\v5.0.100-alpha1-013788\packages\nunit3.dotnetnew.template.1.6.1.nupkg Templates: NUnit 3 Test Project (nunit) C# NUnit 3 Test Item (nunit-test) C# @@ -100,7 +102,7 @@ namespace Templates.Test.Helpers NUnit 3 Test Project (nunit) VB NUnit 3 Test Item (nunit-test) VB Uninstall Command: - dotnet new -u &USERPROFILE%\.templateengine\dotnetcli\v3.0.100-preview7-012821\packages\nunit3.dotnetnew.template.1.6.1.nupkg + dotnet new -u &USERPROFILE%\.templateengine\dotnetcli\v5.0.100-alpha1-013788\packages\nunit3.dotnetnew.template.1.6.1.nupkg * We don't want to construct this path so we'll rely on dotnet new --uninstall --help to construct the uninstall command. */ diff --git a/src/ProjectTemplates/test/IdentityUIPackageTest.cs b/src/ProjectTemplates/test/IdentityUIPackageTest.cs new file mode 100644 index 0000000000..deede64521 --- /dev/null +++ b/src/ProjectTemplates/test/IdentityUIPackageTest.cs @@ -0,0 +1,190 @@ +// 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.Collections.Generic; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class IdentityUIPackageTest + { + public IdentityUIPackageTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; set; } + + public ITestOutputHelper Output { get; } + + public static TheoryData<IDictionary<string, string>, string, string[]> MSBuildIdentityUIPackageOptions + { + get + { + var data = new TheoryData<IDictionary<string, string>, string, string[]>(); + + data.Add(new Dictionary<string, string> + { + ["IdentityUIFrameworkVersion"] = "Bootstrap3" + }, + "Bootstrap v3.4.1", + Bootstrap3ContentFiles); + + data.Add(new Dictionary<string, string>(), "Bootstrap v4.3.1", Bootstrap4ContentFiles); + + return data; + } + } + + public static string[] Bootstrap3ContentFiles { get; } = new string[] + { + "Identity/css/site.css", + "Identity/js/site.js", + "Identity/lib/bootstrap/dist/css/bootstrap-theme.css", + "Identity/lib/bootstrap/dist/css/bootstrap-theme.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap-theme.min.css", + "Identity/lib/bootstrap/dist/css/bootstrap-theme.min.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap.css", + "Identity/lib/bootstrap/dist/css/bootstrap.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap.min.css", + "Identity/lib/bootstrap/dist/css/bootstrap.min.css.map", + "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot", + "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.svg", + "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf", + "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff", + "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2", + "Identity/lib/bootstrap/dist/js/bootstrap.js", + "Identity/lib/bootstrap/dist/js/bootstrap.min.js", + "Identity/lib/bootstrap/dist/js/npm.js", + "Identity/lib/jquery/LICENSE.txt", + "Identity/lib/jquery/dist/jquery.js", + "Identity/lib/jquery/dist/jquery.min.js", + "Identity/lib/jquery/dist/jquery.min.map", + "Identity/lib/jquery-validation/LICENSE.md", + "Identity/lib/jquery-validation/dist/additional-methods.js", + "Identity/lib/jquery-validation/dist/additional-methods.min.js", + "Identity/lib/jquery-validation/dist/jquery.validate.js", + "Identity/lib/jquery-validation/dist/jquery.validate.min.js", + "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", + "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js", + "Identity/lib/jquery-validation-unobtrusive/LICENSE.txt", + }; + + public static string[] Bootstrap4ContentFiles { get; } = new string[] + { + "Identity/favicon.ico", + "Identity/css/site.css", + "Identity/js/site.js", + "Identity/lib/bootstrap/dist/css/bootstrap-grid.css", + "Identity/lib/bootstrap/dist/css/bootstrap-grid.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap-grid.min.css", + "Identity/lib/bootstrap/dist/css/bootstrap-grid.min.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap-reboot.css", + "Identity/lib/bootstrap/dist/css/bootstrap-reboot.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap-reboot.min.css", + "Identity/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap.css", + "Identity/lib/bootstrap/dist/css/bootstrap.css.map", + "Identity/lib/bootstrap/dist/css/bootstrap.min.css", + "Identity/lib/bootstrap/dist/css/bootstrap.min.css.map", + "Identity/lib/bootstrap/dist/js/bootstrap.bundle.js", + "Identity/lib/bootstrap/dist/js/bootstrap.bundle.js.map", + "Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js", + "Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map", + "Identity/lib/bootstrap/dist/js/bootstrap.js", + "Identity/lib/bootstrap/dist/js/bootstrap.js.map", + "Identity/lib/bootstrap/dist/js/bootstrap.min.js", + "Identity/lib/bootstrap/dist/js/bootstrap.min.js.map", + "Identity/lib/jquery/LICENSE.txt", + "Identity/lib/jquery/dist/jquery.js", + "Identity/lib/jquery/dist/jquery.min.js", + "Identity/lib/jquery/dist/jquery.min.map", + "Identity/lib/jquery-validation/LICENSE.md", + "Identity/lib/jquery-validation/dist/additional-methods.js", + "Identity/lib/jquery-validation/dist/additional-methods.min.js", + "Identity/lib/jquery-validation/dist/jquery.validate.js", + "Identity/lib/jquery-validation/dist/jquery.validate.min.js", + "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js", + "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js", + "Identity/lib/jquery-validation-unobtrusive/LICENSE.txt", + }; + + [Theory] + [MemberData(nameof(MSBuildIdentityUIPackageOptions))] + public async Task IdentityUIPackage_WorksWithDifferentOptions(IDictionary<string, string> packageOptions, string versionValidator, string[] expectedFiles) + { + Project = await ProjectFactory.GetOrCreateProject("identityuipackage" + string.Concat(packageOptions.Values), Output); + var useLocalDB = false; + + var createResult = await Project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB, environmentVariables: packageOptions); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); + Assert.Contains(".db", projectFileContents); + + var publishResult = await Project.RunDotNetPublishAsync(packageOptions: packageOptions); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(packageOptions: packageOptions); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("razorpages"); + Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); + Project.AssertEmptyMigration("razorpages"); + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + var response = await aspNetProcess.SendRequest("/Identity/lib/bootstrap/dist/css/bootstrap.css"); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Contains(versionValidator, await response.Content.ReadAsStringAsync()); + await ValidatePublishedFiles(aspNetProcess, expectedFiles); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + var response = await aspNetProcess.SendRequest("/Identity/lib/bootstrap/dist/css/bootstrap.css"); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Contains(versionValidator, await response.Content.ReadAsStringAsync()); + await ValidatePublishedFiles(aspNetProcess, expectedFiles); + } + } + + private async Task ValidatePublishedFiles(AspNetProcess aspNetProcess, string[] expectedContentFiles) + { + foreach (var file in expectedContentFiles) + { + var response = await aspNetProcess.SendRequest(file); + Assert.True(response?.StatusCode == HttpStatusCode.OK, $"Couldn't find file '{file}'"); + } + } + + private string ReadFile(string basePath, string path) + { + var fullPath = Path.Combine(basePath, path); + var doesExist = File.Exists(fullPath); + + Assert.True(doesExist, $"Expected file to exist, but it doesn't: {path}"); + return File.ReadAllText(Path.Combine(basePath, path)); + } + } +} diff --git a/src/ProjectTemplates/test/Infrastructure/Directory.Build.props.in b/src/ProjectTemplates/test/Infrastructure/Directory.Build.props.in index 6186fc2f15..9990532b1d 100644 --- a/src/ProjectTemplates/test/Infrastructure/Directory.Build.props.in +++ b/src/ProjectTemplates/test/Infrastructure/Directory.Build.props.in @@ -1,3 +1,6 @@ <Project> <!-- This file gets copied above the template test projects so that we disconnect the templates from the rest of the repository --> + <PropertyGroup> + <TargetFramework>netcoreapp5.0</TargetFramework> + </PropertyGroup> </Project> diff --git a/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets b/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets index ea67b88cfa..4fa7130601 100644 --- a/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets +++ b/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets @@ -16,9 +16,6 @@ <PropertyGroup> <MicrosoftAspNetCoreAppRefPackageVersion Condition="'$(IsTargetingPackBuilding)' != 'false'">%(_TargetingPackVersionInfo.PackageVersion)</MicrosoftAspNetCoreAppRefPackageVersion> <MicrosoftAspNetCoreAppRefPackageVersion Condition="'$(IsTargetingPackBuilding)' == 'false'">$(AspNetCoreBaselineVersion)</MicrosoftAspNetCoreAppRefPackageVersion> - - <!-- For blazor-wasm we want the runtime to match the baseline, as we want to target the latest released asp.net core app --> - <MicrosoftAspNetCoreAppRuntimePackageVersion>$(AspNetCoreBaselineVersion)</MicrosoftAspNetCoreAppRuntimePackageVersion> </PropertyGroup> <!-- Runtime and Ref packs may have separate versions. --> @@ -37,7 +34,7 @@ MicrosoftNETCorePlatformsPackageVersion=$(MicrosoftNETCorePlatformsPackageVersion); MicrosoftNETSdkRazorPackageVersion=$(MicrosoftNETSdkRazorPackageVersion); MicrosoftAspNetCoreAppRefPackageVersion=$(MicrosoftAspNetCoreAppRefPackageVersion); - MicrosoftAspNetCoreAppRuntimePackageVersion=$(MicrosoftAspNetCoreAppRuntimePackageVersion); + MicrosoftAspNetCoreAppRuntimePackageVersion=@(_RuntimePackageVersionInfo->'%(PackageVersion)'); SupportedRuntimeIdentifiers=$(SupportedRuntimeIdentifiers); DefaultNetCoreTargetFramework=$(DefaultNetCoreTargetFramework); </PropsProperties> diff --git a/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in b/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in index 25fbc524a4..1d3fb7bb2a 100644 --- a/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in +++ b/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in @@ -5,8 +5,6 @@ <!-- This sets an option which prevents the tests from rolling forward into a newer shared framework. --> <UserRuntimeConfig>$(MSBuildThisFileDirectory)runtimeconfig.norollforward.json</UserRuntimeConfig> - <!-- Workaround https://github.com/dotnet/cli/issues/10528 --> - <BundledNETCorePlatformsPackageVersion>${MicrosoftNETCorePlatformsPackageVersion}</BundledNETCorePlatformsPackageVersion> </PropertyGroup> <ItemGroup> @@ -24,15 +22,6 @@ RuntimePackRuntimeIdentifiers="${SupportedRuntimeIdentifiers}" /> </ItemGroup> - <!-- This can be removed after we update our build to use .NET Core Preivew7 SDK or newer. (Needs https://github.com/dotnet/core-sdk/pull/2401) --> - <ItemGroup> - <KnownFrameworkReference - Update="Microsoft.NETCore.App" - RuntimePackNamePatterns="Microsoft.NETCore.App.Runtime.**RID**" - AppHostPackNamePattern="" - AppHostRuntimeIdentifiers="" /> - </ItemGroup> - <ItemGroup> <PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="${MicrosoftNetCompilersToolsetPackageVersion}" diff --git a/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs b/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs new file mode 100644 index 0000000000..842ce8a5d9 --- /dev/null +++ b/src/ProjectTemplates/test/ItemTemplateTests/BlazorServerTests.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Items.Test +{ + public class BlazorServerTest + { + public BlazorServerTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; } + public ITestOutputHelper Output { get; } + + [Fact] + public async Task BlazorServerItemTemplate() + { + Project = await ProjectFactory.GetOrCreateProject("razorcomponentitem", Output); + + var createResult = await Project.RunDotNetNewAsync("razorcomponent --name Different"); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create", Project, createResult)); + + Project.AssertFileExists("Different.razor", shouldExist: true); + Assert.Contains("<h3>Different</h3>", Project.ReadFile("Different.razor")); + } + } +} diff --git a/src/ProjectTemplates/test/MvcTemplateTest.cs b/src/ProjectTemplates/test/MvcTemplateTest.cs new file mode 100644 index 0000000000..c810a45b68 --- /dev/null +++ b/src/ProjectTemplates/test/MvcTemplateTest.cs @@ -0,0 +1,223 @@ +// 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.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Templates.Test.Helpers; +using System.Linq; +using Xunit; +using Xunit.Abstractions; +using Microsoft.AspNetCore.Testing; + +namespace Templates.Test +{ + public class MvcTemplateTest + { + public MvcTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; } + public ITestOutputHelper Output { get; } + + [Fact] + public async Task MvcTemplate_NoAuthFSharp() => await MvcTemplateCore(languageOverride: "F#"); + + [Fact] + public async Task MvcTemplate_NoAuthCSharp() => await MvcTemplateCore(languageOverride: null); + + private async Task MvcTemplateCore(string languageOverride) + { + Project = await ProjectFactory.GetOrCreateProject("mvcnoauth" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); + + var createResult = await Project.RunDotNetNewAsync("mvc", language: languageOverride); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var projectExtension = languageOverride == "F#" ? "fsproj" : "csproj"; + var projectFileContents = Project.ReadFile($"{Project.ProjectName}.{projectExtension}"); + Assert.DoesNotContain(".db", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); + Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); + Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); + + // Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022 + if (languageOverride != null) + { + return; + } + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + IEnumerable<string> menuLinks = new List<string> { + PageUrls.HomeUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyFullUrl + }; + + var footerLinks = new string[] { PageUrls.PrivacyFullUrl }; + + var pages = new List<Page> + { + new Page + { + Url = PageUrls.HomeUrl, + Links = menuLinks.Append(PageUrls.DocsUrl).Concat(footerLinks) + }, + new Page + { + Url = PageUrls.PrivacyFullUrl, + Links = menuLinks.Concat(footerLinks) + } + }; + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task MvcTemplate_IndividualAuth(bool useLocalDB) + { + Project = await ProjectFactory.GetOrCreateProject("mvcindividual" + (useLocalDB ? "uld" : ""), Output); + + var createResult = await Project.RunDotNetNewAsync("mvc", auth: "Individual", useLocalDB: useLocalDB); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var projectFileContents = Project.ReadFile($"{Project.ProjectName}.csproj"); + if (!useLocalDB) + { + Assert.Contains(".db", projectFileContents); + } + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("mvc"); + Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); + Project.AssertEmptyMigration("mvc"); + + var pages = new List<Page> { + new Page + { + Url = PageUrls.ForgotPassword, + Links = new string [] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.HomeUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.DocsUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.PrivacyFullUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.LoginUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.ForgotPassword, + PageUrls.RegisterUrl, + PageUrls.ResendEmailConfirmation, + PageUrls.ExternalArticle, + PageUrls.PrivacyUrl } + }, + new Page + { + Url = PageUrls.RegisterUrl, + Links = new string [] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.ExternalArticle, + PageUrls.PrivacyUrl + } + } + }; + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + } + } +} diff --git a/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj b/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj index 6eb7d6c454..83222ec7aa 100644 --- a/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj +++ b/src/ProjectTemplates/test/ProjectTemplates.Tests.csproj @@ -12,7 +12,7 @@ <SkipTests Condition="'$(RunTemplateTests)' != 'true'">true</SkipTests> <!-- Tests do not work on Helix or when bin/ directory is not in project directory due to undeclared dependency on test content. --> - <!-- https://github.com/aspnet/AspNetCore/issues/6857 --> + <!-- https://github.com/dotnet/aspnetcore/issues/6857 --> <BuildHelixPayload>false</BuildHelixPayload> <BaseOutputPath /> <OutputPath /> @@ -67,6 +67,7 @@ <_Parameter2>true</_Parameter2> </AssemblyAttribute> </ItemGroup> + <Target Name="PrepareForTest" BeforeTargets="CoreCompile" Condition="$(DesignTimeBuild) != true"> <PropertyGroup> <TestTemplateCreationFolder>$([MSBuild]::NormalizePath('$(OutputPath)$(TestTemplateCreationFolder)'))</TestTemplateCreationFolder> diff --git a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs new file mode 100644 index 0000000000..0d02a56f8f --- /dev/null +++ b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs @@ -0,0 +1,62 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class RazorClassLibraryTemplateTest + { + public RazorClassLibraryTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; } + public ITestOutputHelper Output { get; } + + [Fact] + public async Task RazorClassLibraryTemplate_WithViews_Async() + { + Project = await ProjectFactory.GetOrCreateProject("razorclasslibwithviews", Output); + + var createResult = await Project.RunDotNetNewAsync("razorclasslib", args: new[] { "--support-pages-and-views", "true" }); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + } + + [Fact] + public async Task RazorClassLibraryTemplateAsync() + { + Project = await ProjectFactory.GetOrCreateProject("razorclasslib", Output); + + var createResult = await Project.RunDotNetNewAsync("razorclasslib"); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + } + } +} diff --git a/src/ProjectTemplates/test/RazorPagesTemplateTest.cs b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs new file mode 100644 index 0000000000..ad7c967d48 --- /dev/null +++ b/src/ProjectTemplates/test/RazorPagesTemplateTest.cs @@ -0,0 +1,223 @@ +// 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.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class RazorPagesTemplateTest + { + public RazorPagesTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + + public ProjectFactoryFixture ProjectFactory { get; set; } + + public ITestOutputHelper Output { get; } + + [Fact] + public async Task RazorPagesTemplate_NoAuth() + { + Project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output); + + var createResult = await Project.RunDotNetNewAsync("razor"); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("razor", Project, createResult)); + + var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); + Assert.DoesNotContain(".db", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); + Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); + Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); + Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, createResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, createResult)); + + var pages = new List<Page> + { + new Page + { + Url = PageUrls.HomeUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.DocsUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.PrivacyUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.PrivacyUrl } + } + }; + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB) + { + Project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output); + + var createResult = await Project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); + if (!useLocalDB) + { + Assert.Contains(".db", projectFileContents); + } + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("razorpages"); + Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); + Project.AssertEmptyMigration("razorpages"); + + var pages = new List<Page> { + new Page + { + Url = PageUrls.ForgotPassword, + Links = new string [] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.HomeUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.DocsUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.PrivacyUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.PrivacyUrl + } + }, + new Page + { + Url = PageUrls.LoginUrl, + Links = new string[] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.ForgotPassword, + PageUrls.RegisterUrl, + PageUrls.ResendEmailConfirmation, + PageUrls.ExternalArticle, + PageUrls.PrivacyUrl } + }, + new Page + { + Url = PageUrls.RegisterUrl, + Links = new string [] { + PageUrls.HomeUrl, + PageUrls.RegisterUrl, + PageUrls.LoginUrl, + PageUrls.HomeUrl, + PageUrls.PrivacyUrl, + PageUrls.ExternalArticle, + PageUrls.PrivacyUrl + } + } + }; + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertPagesOk(pages); + } + } + + + private string ReadFile(string basePath, string path) + { + var fullPath = Path.Combine(basePath, path); + var doesExist = File.Exists(fullPath); + + Assert.True(doesExist, $"Expected file to exist, but it doesn't: {path}"); + return File.ReadAllText(Path.Combine(basePath, path)); + } + } +} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs new file mode 100644 index 0000000000..e1d5db1338 --- /dev/null +++ b/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.E2ETesting; +using Microsoft.AspNetCore.Testing; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test.SpaTemplateTest +{ + public class AngularTemplateTest : SpaTemplateTestBase + { + public AngularTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) + : base(projectFactory, browserFixture, output) { } + + [Fact] + public Task AngularTemplate_Works() + => SpaTemplateImplAsync("angularnoauth", "angular", useLocalDb: false, usesAuth: false); + + [Fact] + public Task AngularTemplate_IndividualAuth_Works() + => SpaTemplateImplAsync("angularindividual", "angular", useLocalDb: false, usesAuth: true); + + [Fact] + public Task AngularTemplate_IndividualAuth_Works_LocalDb() + => SpaTemplateImplAsync("angularindividualuld", "angular", useLocalDb: true, usesAuth: true); + } +} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs new file mode 100644 index 0000000000..44d6b67f32 --- /dev/null +++ b/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.E2ETesting; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test.SpaTemplateTest +{ + public class ReactReduxTemplateTest : SpaTemplateTestBase + { + public ReactReduxTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) + : base(projectFactory, browserFixture, output) + { + } + + [Fact] + public Task ReactReduxTemplate_Works_NetCore() + => SpaTemplateImplAsync("reactredux", "reactredux", useLocalDb: false, usesAuth: false); + } +} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs new file mode 100644 index 0000000000..469e87acd5 --- /dev/null +++ b/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.E2ETesting; +using Microsoft.AspNetCore.Testing; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test.SpaTemplateTest +{ + public class ReactTemplateTest : SpaTemplateTestBase + { + public ReactTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) + : base(projectFactory, browserFixture, output) + { + } + + [Fact] + public Task ReactTemplate_Works_NetCore() + => SpaTemplateImplAsync("reactnoauth", "react", useLocalDb: false, usesAuth: false); + + [Fact] + public Task ReactTemplate_IndividualAuth_NetCore() + => SpaTemplateImplAsync("reactindividual", "react", useLocalDb: false, usesAuth: true); + + [Fact] + public Task ReactTemplate_IndividualAuth_NetCore_LocalDb() + => SpaTemplateImplAsync("reactindividualuld", "react", useLocalDb: true, usesAuth: true); + } +} diff --git a/src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs b/src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs new file mode 100644 index 0000000000..e630b1f5fd --- /dev/null +++ b/src/ProjectTemplates/test/SpaTemplateTest/SpaTemplateTestBase.cs @@ -0,0 +1,341 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Microsoft.AspNetCore.E2ETesting; +using Newtonsoft.Json.Linq; +using OpenQA.Selenium; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +// Turn off parallel test run for Edge as the driver does not support multiple Selenium tests at the same time +#if EDGE +[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] +#endif +namespace Templates.Test.SpaTemplateTest +{ + public class SpaTemplateTestBase : BrowserTestBase + { + public SpaTemplateTestBase( + ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output) : base(browserFixture, output) + { + ProjectFactory = projectFactory; + } + + public ProjectFactoryFixture ProjectFactory { get; set; } + + public Project Project { get; set; } + + // Rather than using [Theory] to pass each of the different values for 'template', + // it's important to distribute the SPA template tests over different test classes + // so they can be run in parallel. Xunit doesn't parallelize within a test class. + protected async Task SpaTemplateImplAsync( + string key, + string template, + bool useLocalDb = false, + bool usesAuth = false) + { + Project = await ProjectFactory.GetOrCreateProject(key, Output); + + using var createResult = await Project.RunDotNetNewAsync(template, auth: usesAuth ? "Individual" : null, language: null, useLocalDb); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + // We shouldn't have to do the NPM restore in tests because it should happen + // automatically at build time, but by doing it up front we can avoid having + // multiple NPM installs run concurrently which otherwise causes errors when + // tests run in parallel. + var clientAppSubdirPath = Path.Combine(Project.TemplateOutputDir, "ClientApp"); + ValidatePackageJson(clientAppSubdirPath); + + var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); + if (usesAuth && !useLocalDb) + { + Assert.Contains(".db", projectFileContents); + } + + using var npmRestoreResult = await Project.RestoreWithRetryAsync(Output, clientAppSubdirPath); + Assert.True(0 == npmRestoreResult.ExitCode, ErrorMessages.GetFailedProcessMessage("npm restore", Project, npmRestoreResult)); + + using var lintResult = ProcessEx.RunViaShell(Output, clientAppSubdirPath, "npm run lint"); + Assert.True(0 == lintResult.ExitCode, ErrorMessages.GetFailedProcessMessage("npm run lint", Project, lintResult)); + + // The default behavior of angular tests is watch mode, which leaves the test process open after it finishes, which leads to delays/hangs. + var testcommand = "npm run test" + template == "angular" ? "-- --watch=false" : ""; + + using var testResult = ProcessEx.RunViaShell(Output, clientAppSubdirPath, testcommand); + Assert.True(0 == testResult.ExitCode, ErrorMessages.GetFailedProcessMessage("npm run test", Project, testResult)); + + using var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + using var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + // localdb is not installed on the CI machines, so skip it. + var shouldVisitFetchData = !(useLocalDb && Project.IsCIEnvironment); + + if (usesAuth) + { + using var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync(template); + Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); + Project.AssertEmptyMigration(template); + + if (shouldVisitFetchData) + { + using var dbUpdateResult = await Project.RunDotNetEfUpdateDatabaseAsync(); + Assert.True(0 == dbUpdateResult.ExitCode, ErrorMessages.GetFailedProcessMessage("update database", Project, dbUpdateResult)); + } + } + + if (template == "react" || template == "reactredux") + { + await CleanupReactClientAppBuildFolder(clientAppSubdirPath); + } + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await WarmUpServer(aspNetProcess); + await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); + + if (BrowserFixture.IsHostAutomationSupported()) + { + var (browser, logs) = await BrowserFixture.GetOrCreateBrowserAsync(Output, $"{Project.ProjectName}.build"); + aspNetProcess.VisitInBrowser(browser); + TestBasicNavigation(visitFetchData: shouldVisitFetchData, usesAuth, browser, logs); + } + else + { + BrowserFixture.EnforceSupportedConfigurations(); + } + } + + if (usesAuth) + { + UpdatePublishedSettings(); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + await WarmUpServer(aspNetProcess); + await aspNetProcess.AssertStatusCode("/", HttpStatusCode.OK, "text/html"); + + if (BrowserFixture.IsHostAutomationSupported()) + { + var (browser, logs) = await BrowserFixture.GetOrCreateBrowserAsync(Output, $"{Project.ProjectName}.publish"); + aspNetProcess.VisitInBrowser(browser); + TestBasicNavigation(visitFetchData: shouldVisitFetchData, usesAuth, browser, logs); + } + else + { + BrowserFixture.EnforceSupportedConfigurations(); + } + } + } + + private async Task CleanupReactClientAppBuildFolder(string clientAppSubdirPath) + { + ProcessEx testResult = null; + int? testResultExitCode = null; + for (int i = 0; i < 3; i++) + { + try + { + testResult = ProcessEx.RunViaShell(Output, clientAppSubdirPath, "npx rimraf ./build"); + testResultExitCode = testResult.ExitCode; + if (testResultExitCode == 0) + { + return; + } + } + catch + { + } + finally + { + testResult.Dispose(); + } + + await Task.Delay(3000); + } + + Assert.True(testResultExitCode == 0, ErrorMessages.GetFailedProcessMessage("npx rimraf ./build", Project, testResult)); + } + + private void ValidatePackageJson(string clientAppSubdirPath) + { + Assert.True(File.Exists(Path.Combine(clientAppSubdirPath, "package.json")), "Missing a package.json"); + var packageJson = JObject.Parse(ReadFile(clientAppSubdirPath, "package.json")); + + // NPM package names must match ^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$ + var packageName = (string)packageJson["name"]; + Regex regex = new Regex("^(?:@[a-z0-9-~][a-z0-9-._~]*/)?[a-z0-9-~][a-z0-9-._~]*$"); + Assert.True(regex.IsMatch(packageName), "package.json name is invalid format"); + } + + private static async Task WarmUpServer(AspNetProcess aspNetProcess) + { + var attempt = 0; + var maxAttempts = 3; + do + { + try + { + attempt++; + var response = await aspNetProcess.SendRequest("/"); + if (response.StatusCode == HttpStatusCode.OK) + { + break; + } + } + catch (OperationCanceledException) + { + } + catch (HttpRequestException ex) when (ex.Message.StartsWith("The SSL connection could not be established")) + { + } + await Task.Delay(TimeSpan.FromSeconds(10 * attempt)); + } while (attempt < maxAttempts); + } + + private void UpdatePublishedSettings() + { + // Hijack here the config file to use the development key during publish. + var appSettings = JObject.Parse(File.ReadAllText(Path.Combine(Project.TemplateOutputDir, "appsettings.json"))); + var appSettingsDevelopment = JObject.Parse(File.ReadAllText(Path.Combine(Project.TemplateOutputDir, "appsettings.Development.json"))); + ((JObject)appSettings["IdentityServer"]).Merge(appSettingsDevelopment["IdentityServer"]); + ((JObject)appSettings["IdentityServer"]).Merge(new + { + IdentityServer = new + { + Key = new + { + FilePath = "./tempkey.json" + } + } + }); + var testAppSettings = appSettings.ToString(); + File.WriteAllText(Path.Combine(Project.TemplatePublishDir, "appsettings.json"), testAppSettings); + } + + private void TestBasicNavigation(bool visitFetchData, bool usesAuth, IWebDriver browser, ILogs logs) + { + browser.Exists(By.TagName("ul")); + // <title> element gets project ID injected into it during template execution + browser.Contains(Project.ProjectGuid.Replace(".", "._"), () => browser.Title); + + // Initially displays the home page + browser.Equal("Hello, world!", () => browser.FindElement(By.TagName("h1")).Text); + + // Can navigate to the counter page + browser.FindElement(By.PartialLinkText("Counter")).Click(); + browser.Contains("counter", () => browser.Url); + + browser.Equal("Counter", () => browser.FindElement(By.TagName("h1")).Text); + + // Clicking the counter button works + browser.Equal("0", () => browser.FindElement(By.CssSelector("p>strong")).Text); + browser.FindElement(By.CssSelector("p+button")).Click(); + browser.Equal("1", () => browser.FindElement(By.CssSelector("p>strong")).Text); + + if (visitFetchData) + { + browser.FindElement(By.PartialLinkText("Fetch data")).Click(); + + if (usesAuth) + { + // We will be redirected to the identity UI + browser.Contains("/Identity/Account/Login", () => browser.Url); + browser.FindElement(By.PartialLinkText("Register as a new user")).Click(); + + var userName = $"{Guid.NewGuid()}@example.com"; + var password = $"!Test.Password1$"; + browser.Exists(By.Name("Input.Email")); + browser.FindElement(By.Name("Input.Email")).SendKeys(userName); + browser.FindElement(By.Name("Input.Password")).SendKeys(password); + browser.FindElement(By.Name("Input.ConfirmPassword")).SendKeys(password); + browser.FindElement(By.Id("registerSubmit")).Click(); + + // We will be redirected to the RegisterConfirmation + browser.Contains("/Identity/Account/RegisterConfirmation", () => browser.Url); + browser.FindElement(By.PartialLinkText("Click here to confirm your account")).Click(); + + // We will be redirected to the ConfirmEmail + browser.Contains("/Identity/Account/ConfirmEmail", () => browser.Url); + + // Now we can login + browser.FindElement(By.PartialLinkText("Login")).Click(); + browser.Exists(By.Name("Input.Email")); + browser.FindElement(By.Name("Input.Email")).SendKeys(userName); + browser.FindElement(By.Name("Input.Password")).SendKeys(password); + browser.FindElement(By.Id("login-submit")).Click(); + + // Need to navigate to fetch page + browser.FindElement(By.PartialLinkText("Fetch data")).Click(); + } + + // Can navigate to the 'fetch data' page + browser.Contains("fetch-data", () => browser.Url); + browser.Equal("Weather forecast", () => browser.FindElement(By.TagName("h1")).Text); + + // Asynchronously loads and displays the table of weather forecasts + browser.Exists(By.CssSelector("table>tbody>tr")); + browser.Equal(5, () => browser.FindElements(By.CssSelector("p+table>tbody>tr")).Count); + } + + foreach (var logKind in logs.AvailableLogTypes) + { + var entries = logs.GetLog(logKind); + var badEntries = entries.Where(e => new LogLevel[] { LogLevel.Warning, LogLevel.Severe }.Contains(e.Level)); + + // Based on https://github.com/webpack/webpack-dev-server/issues/2134 + badEntries = badEntries.Where(e => + !e.Message.Contains("failed: WebSocket is closed before the connection is established.") + && !e.Message.Contains("[WDS] Disconnected!") + && !e.Message.Contains("Timed out connecting to Chrome, retrying") + && !(e.Message.Contains("jsonp?c=") && e.Message.Contains("Uncaught TypeError:") && e.Message.Contains("is not a function"))); + + Assert.True(badEntries.Count() == 0, "There were Warnings or Errors from the browser." + Environment.NewLine + string.Join(Environment.NewLine, badEntries)); + } + } + + private void AssertFileExists(string basePath, string path, bool shouldExist) + { + var fullPath = Path.Combine(basePath, path); + var doesExist = File.Exists(fullPath); + + if (shouldExist) + { + Assert.True(doesExist, "Expected file to exist, but it doesn't: " + path); + } + else + { + Assert.False(doesExist, "Expected file not to exist, but it does: " + path); + } + } + + private string ReadFile(string basePath, string path) + { + AssertFileExists(basePath, path, shouldExist: true); + return File.ReadAllText(Path.Combine(basePath, path)); + } + } +} diff --git a/src/ProjectTemplates/test/WebApiTemplateTest.cs b/src/ProjectTemplates/test/WebApiTemplateTest.cs new file mode 100644 index 0000000000..375f292472 --- /dev/null +++ b/src/ProjectTemplates/test/WebApiTemplateTest.cs @@ -0,0 +1,76 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class WebApiTemplateTest + { + public WebApiTemplateTest(ProjectFactoryFixture factoryFixture, ITestOutputHelper output) + { + FactoryFixture = factoryFixture; + Output = output; + } + + public ProjectFactoryFixture FactoryFixture { get; } + + public ITestOutputHelper Output { get; } + + public Project Project { get; set; } + + [Fact] + public async Task WebApiTemplateFSharp() => await WebApiTemplateCore(languageOverride: "F#"); + + [Fact] + public async Task WebApiTemplateCSharp() => await WebApiTemplateCore(languageOverride: null); + + private async Task WebApiTemplateCore(string languageOverride) + { + Project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output); + + var createResult = await Project.RunDotNetNewAsync("webapi", language: languageOverride); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + // Avoid the F# compiler. See https://github.com/dotnet/aspnetcore/issues/14022 + if (languageOverride != null) + { + return; + } + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + using (var aspNetProcess = Project.StartBuiltProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + + await aspNetProcess.AssertOk("weatherforecast"); + await aspNetProcess.AssertNotFound("/"); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync()) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + + + await aspNetProcess.AssertOk("weatherforecast"); + await aspNetProcess.AssertNotFound("/"); + } + } + } +} diff --git a/src/ProjectTemplates/test/WorkerTemplateTest.cs b/src/ProjectTemplates/test/WorkerTemplateTest.cs new file mode 100644 index 0000000000..738eafc61d --- /dev/null +++ b/src/ProjectTemplates/test/WorkerTemplateTest.cs @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Templates.Test.Helpers; +using Xunit; +using Xunit.Abstractions; + +namespace Templates.Test +{ + public class WorkerTemplateTest + { + public WorkerTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) + { + ProjectFactory = projectFactory; + Output = output; + } + + public Project Project { get; set; } + public ProjectFactoryFixture ProjectFactory { get; } + public ITestOutputHelper Output { get; } + + [Fact] + public async Task WorkerTemplateAsync() + { + Project = await ProjectFactory.GetOrCreateProject("worker", Output); + + var createResult = await Project.RunDotNetNewAsync("worker"); + Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); + + var publishResult = await Project.RunDotNetPublishAsync(); + Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); + + // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release + // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build + // later, while the opposite is not true. + + var buildResult = await Project.RunDotNetBuildAsync(); + Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); + + using (var aspNetProcess = Project.StartBuiltProjectAsync(hasListeningUri: false)) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); + } + + using (var aspNetProcess = Project.StartPublishedProjectAsync(hasListeningUri: false)) + { + Assert.False( + aspNetProcess.Process.HasExited, + ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); + } + } + } +} diff --git a/src/ProjectTemplates/test/template-baselines.json b/src/ProjectTemplates/test/template-baselines.json index d934d8b545..618bb27a1f 100644 --- a/src/ProjectTemplates/test/template-baselines.json +++ b/src/ProjectTemplates/test/template-baselines.json @@ -1209,6 +1209,7 @@ "ClientApp/src/App.test.js", "ClientApp/src/index.js", "ClientApp/src/registerServiceWorker.js", + "ClientApp/.env", "ClientApp/.gitignore", "ClientApp/package-lock.json", "ClientApp/package.json", @@ -1251,6 +1252,7 @@ "ClientApp/src/index.tsx", "ClientApp/src/react-app-env.d.ts", "ClientApp/src/registerServiceWorker.ts", + "ClientApp/.env", "ClientApp/.eslintrc.json", "ClientApp/.gitignore", "ClientApp/package-lock.json", diff --git a/src/Razor/Razor.Runtime/ref/Microsoft.AspNetCore.Razor.Runtime.netcoreapp.cs b/src/Razor/Razor.Runtime/ref/Microsoft.AspNetCore.Razor.Runtime.netcoreapp.cs index 9e2eb73d09..c8bd4d24f6 100644 --- a/src/Razor/Razor.Runtime/ref/Microsoft.AspNetCore.Razor.Runtime.netcoreapp.cs +++ b/src/Razor/Razor.Runtime/ref/Microsoft.AspNetCore.Razor.Runtime.netcoreapp.cs @@ -21,9 +21,9 @@ namespace Microsoft.AspNetCore.Razor.Hosting public sealed partial class RazorCompiledItemAttribute : System.Attribute { public RazorCompiledItemAttribute(System.Type type, string kind, string identifier) { } - public string Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Kind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Kind { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type Type { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class RazorCompiledItemExtensions { @@ -40,35 +40,35 @@ namespace Microsoft.AspNetCore.Razor.Hosting public sealed partial class RazorCompiledItemMetadataAttribute : System.Attribute { public RazorCompiledItemMetadataAttribute(string key, string value) { } - public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Key { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public sealed partial class RazorConfigurationNameAttribute : System.Attribute { public RazorConfigurationNameAttribute(string configurationName) { } - public string ConfigurationName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ConfigurationName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)] public sealed partial class RazorExtensionAssemblyNameAttribute : System.Attribute { public RazorExtensionAssemblyNameAttribute(string extensionName, string assemblyName) { } - public string AssemblyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ExtensionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AssemblyName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ExtensionName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public sealed partial class RazorLanguageVersionAttribute : System.Attribute { public RazorLanguageVersionAttribute(string languageVersion) { } - public string LanguageVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string LanguageVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Class, AllowMultiple=true, Inherited=true)] public sealed partial class RazorSourceChecksumAttribute : System.Attribute, Microsoft.AspNetCore.Razor.Hosting.IRazorSourceChecksumMetadata { public RazorSourceChecksumAttribute(string checksumAlgorithm, string checksum, string identifier) { } - public string Checksum { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ChecksumAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Checksum { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ChecksumAlgorithm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Identifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers @@ -77,9 +77,9 @@ namespace Microsoft.AspNetCore.Razor.Runtime.TagHelpers { public TagHelperExecutionContext(string tagName, Microsoft.AspNetCore.Razor.TagHelpers.TagMode tagMode, System.Collections.Generic.IDictionary<object, object> items, string uniqueId, System.Func<System.Threading.Tasks.Task> executeChildContentAsync, System.Action<System.Text.Encodings.Web.HtmlEncoder> startTagHelperWritingScope, System.Func<Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent> endTagHelperWritingScope) { } public bool ChildContentRetrieved { get { throw null; } } - public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput Output { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput Output { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IList<Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper> TagHelpers { get { throw null; } } public void Add(Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper tagHelper) { } public void AddHtmlAttribute(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute attribute) { } diff --git a/src/Razor/Razor/ref/Microsoft.AspNetCore.Razor.netcoreapp.cs b/src/Razor/Razor/ref/Microsoft.AspNetCore.Razor.netcoreapp.cs index 36d08aa6ae..de54d56596 100644 --- a/src/Razor/Razor/ref/Microsoft.AspNetCore.Razor.netcoreapp.cs +++ b/src/Razor/Razor/ref/Microsoft.AspNetCore.Razor.netcoreapp.cs @@ -26,8 +26,8 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public HtmlAttributeNameAttribute() { } public HtmlAttributeNameAttribute(string name) { } public string DictionaryAttributePrefix { get { throw null; } set { } } - public bool DictionaryAttributePrefixSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool DictionaryAttributePrefixSet { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Property, AllowMultiple=false, Inherited=false)] public sealed partial class HtmlAttributeNotBoundAttribute : System.Attribute @@ -47,10 +47,10 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public const string ElementCatchAllTarget = "*"; public HtmlTargetElementAttribute() { } public HtmlTargetElementAttribute(string tag) { } - public string Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ParentTag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Tag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Razor.TagHelpers.TagStructure TagStructure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ParentTag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Tag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Razor.TagHelpers.TagStructure TagStructure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial interface ITagHelper : Microsoft.AspNetCore.Razor.TagHelpers.ITagHelperComponent { @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public sealed partial class NullHtmlEncoder : System.Text.Encodings.Web.HtmlEncoder { internal NullHtmlEncoder() { } - public static new Microsoft.AspNetCore.Razor.TagHelpers.NullHtmlEncoder Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public static new Microsoft.AspNetCore.Razor.TagHelpers.NullHtmlEncoder Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override int MaxOutputCharactersPerInputCharacter { get { throw null; } } public override void Encode(System.IO.TextWriter output, char[] value, int startIndex, int characterCount) { } public override void Encode(System.IO.TextWriter output, string value, int startIndex, int characterCount) { } @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public sealed partial class OutputElementHintAttribute : System.Attribute { public OutputElementHintAttribute(string outputElement) { } - public string OutputElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string OutputElement { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class ReadOnlyTagHelperAttributeList : System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute> { @@ -94,12 +94,12 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public sealed partial class RestrictChildrenAttribute : System.Attribute { public RestrictChildrenAttribute(string childTag, params string[] childTags) { } - public System.Collections.Generic.IEnumerable<string> ChildTags { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable<string> ChildTags { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class TagHelper : Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper, Microsoft.AspNetCore.Razor.TagHelpers.ITagHelperComponent { protected TagHelper() { } - public virtual int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual void Init(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context) { } public virtual void Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { } public virtual System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) { throw null; } @@ -109,9 +109,9 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public TagHelperAttribute(string name) { } public TagHelperAttribute(string name, object value) { } public TagHelperAttribute(string name, object value, Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle valueStyle) { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle ValueStyle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle ValueStyle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void CopyTo(Microsoft.AspNetCore.Html.IHtmlContentBuilder destination) { } public bool Equals(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute other) { throw null; } public override bool Equals(object obj) { throw null; } @@ -174,24 +174,24 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers public TagHelperContext(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttributeList allAttributes, System.Collections.Generic.IDictionary<object, object> items, string uniqueId) { } public TagHelperContext(string tagName, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttributeList allAttributes, System.Collections.Generic.IDictionary<object, object> items, string uniqueId) { } public Microsoft.AspNetCore.Razor.TagHelpers.ReadOnlyTagHelperAttributeList AllAttributes { get { throw null; } } - public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string TagName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string UniqueId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string TagName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string UniqueId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Reinitialize(System.Collections.Generic.IDictionary<object, object> items, string uniqueId) { } public void Reinitialize(string tagName, System.Collections.Generic.IDictionary<object, object> items, string uniqueId) { } } public partial class TagHelperOutput : Microsoft.AspNetCore.Html.IHtmlContent, Microsoft.AspNetCore.Html.IHtmlContentContainer { public TagHelperOutput(string tagName, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttributeList attributes, System.Func<bool, System.Text.Encodings.Web.HtmlEncoder, System.Threading.Tasks.Task<Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent>> getChildContentAsync) { } - public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttributeList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttributeList Attributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent Content { get { throw null; } set { } } public bool IsContentModified { get { throw null; } } public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent PostContent { get { throw null; } } public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent PostElement { get { throw null; } } public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent PreContent { get { throw null; } } public Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent PreElement { get { throw null; } } - public Microsoft.AspNetCore.Razor.TagHelpers.TagMode TagMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string TagName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Razor.TagHelpers.TagMode TagMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string TagName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Threading.Tasks.Task<Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent> GetChildContentAsync() { throw null; } public System.Threading.Tasks.Task<Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent> GetChildContentAsync(bool useCachedResult) { throw null; } public System.Threading.Tasks.Task<Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContent> GetChildContentAsync(bool useCachedResult, System.Text.Encodings.Web.HtmlEncoder encoder) { throw null; } diff --git a/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs b/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs index 7fa9e147ab..ecd78d5680 100644 --- a/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs +++ b/src/Security/Authentication/Certificate/ref/Microsoft.AspNetCore.Authentication.Certificate.netcoreapp.cs @@ -10,25 +10,25 @@ namespace Microsoft.AspNetCore.Authentication.Certificate public partial class CertificateAuthenticationEvents { public CertificateAuthenticationEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Certificate.CertificateValidatedContext, System.Threading.Tasks.Task> OnCertificateValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Certificate.CertificateValidatedContext, System.Threading.Tasks.Task> OnCertificateValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task AuthenticationFailed(Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationFailedContext context) { throw null; } public virtual System.Threading.Tasks.Task CertificateValidated(Microsoft.AspNetCore.Authentication.Certificate.CertificateValidatedContext context) { throw null; } } public partial class CertificateAuthenticationFailedContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions> { public CertificateAuthenticationFailedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions)) { } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CertificateAuthenticationOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { public CertificateAuthenticationOptions() { } - public Microsoft.AspNetCore.Authentication.Certificate.CertificateTypes AllowedCertificateTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.Certificate.CertificateTypes AllowedCertificateTypes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationEvents Events { get { throw null; } set { } } - public System.Security.Cryptography.X509Certificates.X509RevocationFlag RevocationFlag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Cryptography.X509Certificates.X509RevocationMode RevocationMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ValidateCertificateUse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ValidateValidityPeriod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Cryptography.X509Certificates.X509RevocationFlag RevocationFlag { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Cryptography.X509Certificates.X509RevocationMode RevocationMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ValidateCertificateUse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ValidateValidityPeriod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } [System.FlagsAttribute] public enum CertificateTypes @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Authentication.Certificate public partial class CertificateValidatedContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions> { public CertificateValidatedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Certificate.CertificateAuthenticationOptions)) { } - public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class X509Certificate2Extensions { diff --git a/src/Security/Authentication/Certificate/src/README-IISConfig.png b/src/Security/Authentication/Certificate/src/README-IISConfig.png deleted file mode 100644 index 3af15e9d06..0000000000 Binary files a/src/Security/Authentication/Certificate/src/README-IISConfig.png and /dev/null differ diff --git a/src/Security/Authentication/Certificate/src/README.md b/src/Security/Authentication/Certificate/src/README.md index 542131fdf1..a589666e0a 100644 --- a/src/Security/Authentication/Certificate/src/README.md +++ b/src/Security/Authentication/Certificate/src/README.md @@ -1,234 +1,5 @@ # Microsoft.AspNetCore.Authentication.Certificate - -This project sort of contains an implementation of [Certificate Authentication](https://tools.ietf.org/html/rfc5246#section-7.4.4) for ASP.NET Core. -Certificate authentication happens at the TLS level, long before it ever gets to ASP.NET Core, so, more accurately this is an authentication handler -that validates the certificate and then gives you an event where you can resolve that certificate to a ClaimsPrincipal. -You **must** [configure your host](#hostConfiguration) for certificate authentication, be it IIS, Kestrel, Azure Web Applications or whatever else you're using. - -## Getting started - -First acquire an HTTPS certificate, apply it and then [configure your host](#hostConfiguration) to require certificates. - -In your web application add a reference to the package, then in the `ConfigureServices` method in `startup.cs` call -`app.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).UseCertificateAuthentication(...);` with your options, -providing a delegate for `OnValidateCertificate` to validate the client certificate sent with requests and turn that information -into an `ClaimsPrincipal`, set it on the `context.Principal` property and call `context.Success()`. - -If you change your scheme name in the options for the authentication handler you need to change the scheme name in -`AddAuthentication()` to ensure it's used on every request which ends in an endpoint that requires authorization. - -If authentication fails this handler will return a `403 (Forbidden)` response rather a `401 (Unauthorized)` as you -might expect - this is because the authentication should happen during the initial TLS connection - by the time it -reaches the handler it's too late, and there's no way to actually upgrade the connection from an anonymous connection -to one with a certificate. - -You must also add `app.UseAuthentication();` in the `Configure` method, otherwise nothing will ever get called. - -For example; - -```c# -public void ConfigureServices(IServiceCollection services) -{ - services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme) - .AddCertificate(); - // All the other service configuration. -} - -public void Configure(IApplicationBuilder app, IHostingEnvironment env) -{ - app.UseAuthentication(); - - // All the other app configuration. -} -``` - -In the sample above you can see the default way to add certificate authentication. The handler will construct a user principal using the common certificate properties for you. - -## Configuring Certificate Validation - -The `CertificateAuthenticationOptions` handler has some built in validations that are the minimium validations you should perform on -a certificate. Each of these settings are turned on by default. - -### ValidateCertificateChain - -This check validates that the issuer for the certificate is trusted by the application host OS. If -you are going to accept self-signed certificates you must disable this check. - -### ValidateCertificateUse - -This check validates that the certificate presented by the client has the Client Authentication -extended key use, or no EKUs at all (as the specifications say if no EKU is specified then all EKUs -are valid). - -### ValidateValidityPeriod - -This check validates that the certificate is within its validity period. As the handler runs on every -request this ensures that a certificate that was valid when it was presented has not expired during -its current session. - -### RevocationFlag - -A flag which specifies which certificates in the chain are checked for revocation. - -Revocation checks are only performed when the certificate is chained to a root certificate. - -### RevocationMode - -A flag which specifies how revocation checks are performed. -Specifying an on-line check can result in a long delay while the certificate authority is contacted. - -Revocation checks are only performed when the certificate is chained to a root certificate. - -### Can I configure my application to require a certificate only on certain paths? - -Not possible, remember the certificate exchange is done that the start of the HTTPS conversation, -it's done by the host, not the application. Kestrel, IIS, Azure Web Apps don't have any configuration for -this sort of thing. - -# Handler events - -The handler has two events, `OnAuthenticationFailed()`, which is called if an exception happens during authentication and allows you to react, and `OnValidateCertificate()` which is -called after certificate has been validated, passed validation, abut before the default principal has been created. This allows you to perform your own validation, for example -checking if the certificate is one your services knows about, and to construct your own principal. For example, - -```c# -services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme) - .AddCertificate(options => - { - options.Events = new CertificateAuthenticationEvents - { - OnValidateCertificate = context => - { - var claims = new[] - { - new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer), - new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer) - }; - - context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name)); - context.Success(); - - return Task.CompletedTask; - } - }; - }); -``` - -If you find the inbound certificate doesn't meet your extra validation call `context.Fail("failure Reason")` with a failure reason. - -For real functionality you will probably want to call a service registered in DI which talks to a database or other type of -user store. You can grab your service by using the context passed into your delegates, like so - -```c# -services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme) - .AddCertificate(options => - { - options.Events = new CertificateAuthenticationEvents - { - OnCertificateValidated = context => - { - var validationService = - context.HttpContext.RequestServices.GetService<ICertificateValidationService>(); - - if (validationService.ValidateCertificate(context.ClientCertificate)) - { - var claims = new[] - { - new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer), - new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer) - }; - - context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name)); - context.Success(); - } - - return Task.CompletedTask; - } - }; - }); -``` -Note that conceptually the validation of the certification is an authorization concern, and putting a check on, for example, an issuer or thumbprint in an authorization policy rather -than inside OnCertificateValidated() is perfectly acceptable. - -## <a name="hostConfiguration"></a>Configuring your host to require certificates - -### Kestrel - -In program.cs configure `UseKestrel()` as follows. - -```c# -public static IWebHost BuildWebHost(string[] args) - => WebHost.CreateDefaultBuilder(args) - .UseStartup<Startup>() - .ConfigureKestrel(options => - { - options.ConfigureHttpsDefaults(opt => - { - opt.ClientCertificateMode = ClientCertificateMode.RequireCertificate; - }); - }) - .Build(); -``` -You must set the `ClientCertificateValidation` delegate to `CertificateValidator.DisableChannelValidation` in order to stop Kestrel using the default OS certificate validation routine and, -instead, letting the authentication handler perform the validation. - -### IIS - -In the IIS Manager - -1. Select your Site in the Connections tab. -2. Double click the SSL Settings in the Features View window. -3. Check the `Require SSL` Check Box and select the `Require` radio button under Client Certificates. - -![Client Certificate Settings in IIS](README-IISConfig.png "Client Certificate Settings in IIS") - -### Azure - -See the [Azure documentation](https://docs.microsoft.com/en-us/azure/app-service/app-service-web-configure-tls-mutual-auth) -to configure Azure Web Apps then add the following to your application startup method, `Configure(IApplicationBuilder app)` add the -following line before the call to `app.UseAuthentication();` - -```c# -app.UseCertificateHeaderForwarding(); -``` - -### Random custom web proxies - -If you're using a proxy which isn't IIS or Azure's Web Apps Application Request Routing you will need to configure your proxy -to forward the certificate it received in an HTTP header. -In your application startup method, `Configure(IApplicationBuilder app)`, add the -following line before the call to `app.UseAuthentication();` - -```c# -app.UseCertificateForwarding(); -``` - -You will also need to configure the Certificate Forwarding middleware to specify the header name. -In your service configuration method, `ConfigureServices(IServiceCollection services)` add -the following code to configure the header the forwarding middleware will build a certificate from; - -```c# -services.AddCertificateForwarding(options => -{ - options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME"; -}); -``` - -Finally, if your proxy is doing something weird to pass the header on, rather than base 64 encoding it -(looking at you nginx (╯°□°)╯︵ ┻━┻) you can override the converter option to be a func that will -perform the optional conversion, for example - -```c# -services.AddCertificateForwarding(options => -{ - options.CertificateHeader = "YOUR_CUSTOM_HEADER_NAME"; - options.HeaderConverter = (headerValue) => - { - var clientCertificate = - /* some weird conversion logic to create an X509Certificate2 */ - return clientCertificate; - } -}); -``` +This project sort of contains an implementation of [Certificate Authentication](https://tools.ietf.org/html/rfc5246#section-7.4.4) for ASP.NET Core. Certificate authentication happens at the TLS level, long before it ever gets to ASP.NET Core, so, more accurately this is an authentication handler that validates the certificate and then gives you an event where you can resolve that certificate to a ClaimsPrincipal. +For more information, see [Configure certificate authentication in ASP.NET Core](https://docs.microsoft.com/aspnet/core/security/authentication/certauth). diff --git a/src/Security/Authentication/Cookies/ref/Microsoft.AspNetCore.Authentication.Cookies.netcoreapp.cs b/src/Security/Authentication/Cookies/ref/Microsoft.AspNetCore.Authentication.Cookies.netcoreapp.cs index d9457f3861..f3d730a1f9 100644 --- a/src/Security/Authentication/Cookies/ref/Microsoft.AspNetCore.Authentication.Cookies.netcoreapp.cs +++ b/src/Security/Authentication/Cookies/ref/Microsoft.AspNetCore.Authentication.Cookies.netcoreapp.cs @@ -7,8 +7,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies { public const int DefaultChunkSize = 4050; public ChunkingCookieManager() { } - public int? ChunkSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ThrowForPartialCookies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int? ChunkSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ThrowForPartialCookies { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void AppendResponseCookie(Microsoft.AspNetCore.Http.HttpContext context, string key, string value, Microsoft.AspNetCore.Http.CookieOptions options) { } public void DeleteCookie(Microsoft.AspNetCore.Http.HttpContext context, string key, Microsoft.AspNetCore.Http.CookieOptions options) { } public string GetRequestCookie(Microsoft.AspNetCore.Http.HttpContext context, string key) { throw null; } @@ -25,14 +25,14 @@ namespace Microsoft.AspNetCore.Authentication.Cookies public partial class CookieAuthenticationEvents { public CookieAuthenticationEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToAccessDenied { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToLogin { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToLogout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieSignedInContext, System.Threading.Tasks.Task> OnSignedIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieSigningInContext, System.Threading.Tasks.Task> OnSigningIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieSigningOutContext, System.Threading.Tasks.Task> OnSigningOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext, System.Threading.Tasks.Task> OnValidatePrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToAccessDenied { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToLogin { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToLogout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions>, System.Threading.Tasks.Task> OnRedirectToReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieSignedInContext, System.Threading.Tasks.Task> OnSignedIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieSigningInContext, System.Threading.Tasks.Task> OnSigningIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieSigningOutContext, System.Threading.Tasks.Task> OnSigningOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Cookies.CookieValidatePrincipalContext, System.Threading.Tasks.Task> OnValidatePrincipal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task RedirectToAccessDenied(Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> context) { throw null; } public virtual System.Threading.Tasks.Task RedirectToLogin(Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> context) { throw null; } public virtual System.Threading.Tasks.Task RedirectToLogout(Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> context) { throw null; } @@ -64,18 +64,18 @@ namespace Microsoft.AspNetCore.Authentication.Cookies public partial class CookieAuthenticationOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { public CookieAuthenticationOptions() { } - public Microsoft.AspNetCore.Http.PathString AccessDeniedPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.PathString AccessDeniedPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.CookieBuilder Cookie { get { throw null; } set { } } - public Microsoft.AspNetCore.Authentication.Cookies.ICookieManager CookieManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.DataProtection.IDataProtectionProvider DataProtectionProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.Cookies.ICookieManager CookieManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.DataProtection.IDataProtectionProvider DataProtectionProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationEvents Events { get { throw null; } set { } } - public System.TimeSpan ExpireTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString LoginPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString LogoutPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrlParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.Cookies.ITicketStore SessionStore { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SlidingExpiration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationTicket> TicketDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan ExpireTimeSpan { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString LoginPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString LogoutPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrlParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.Cookies.ITicketStore SessionStore { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SlidingExpiration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationTicket> TicketDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CookieSignedInContext : Microsoft.AspNetCore.Authentication.PrincipalContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> { @@ -84,17 +84,17 @@ namespace Microsoft.AspNetCore.Authentication.Cookies public partial class CookieSigningInContext : Microsoft.AspNetCore.Authentication.PrincipalContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> { public CookieSigningInContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions options, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, Microsoft.AspNetCore.Http.CookieOptions cookieOptions) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CookieSigningOutContext : Microsoft.AspNetCore.Authentication.PropertiesContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> { public CookieSigningOutContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, Microsoft.AspNetCore.Http.CookieOptions cookieOptions) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CookieValidatePrincipalContext : Microsoft.AspNetCore.Authentication.PrincipalContext<Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions> { public CookieValidatePrincipalContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationTicket ticket) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public bool ShouldRenew { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool ShouldRenew { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void RejectPrincipal() { } public void ReplacePrincipal(System.Security.Claims.ClaimsPrincipal principal) { } } diff --git a/src/Security/Authentication/Cookies/src/CookieAuthenticationOptions.cs b/src/Security/Authentication/Cookies/src/CookieAuthenticationOptions.cs index fc4edaa3dd..0248669979 100644 --- a/src/Security/Authentication/Cookies/src/CookieAuthenticationOptions.cs +++ b/src/Security/Authentication/Cookies/src/CookieAuthenticationOptions.cs @@ -39,27 +39,27 @@ namespace Microsoft.AspNetCore.Authentication.Cookies /// Determines the settings used to create the cookie. /// </para> /// <para> - /// <seealso cref="CookieBuilder.SameSite"/> defaults to <see cref="SameSiteMode.Lax"/>. - /// <seealso cref="CookieBuilder.HttpOnly"/> defaults to <c>true</c>. - /// <seealso cref="CookieBuilder.SecurePolicy"/> defaults to <see cref="CookieSecurePolicy.SameAsRequest"/>. + /// <see cref="CookieBuilder.SameSite"/> defaults to <see cref="SameSiteMode.Lax"/>. + /// <see cref="CookieBuilder.HttpOnly"/> defaults to <c>true</c>. + /// <see cref="CookieBuilder.SecurePolicy"/> defaults to <see cref="CookieSecurePolicy.SameAsRequest"/>. /// </para> /// </summary> /// <remarks> /// <para> - /// The default value for cookie name is ".AspNetCore.Cookies". - /// This value should be changed if you change the name of the AuthenticationScheme, especially if your + /// The default value for cookie <see cref="CookieBuilder.Name"/> is ".AspNetCore.Cookies". + /// This value should be changed if you change the name of the <c>AuthenticationScheme</c>, especially if your /// system uses the cookie authentication handler multiple times. /// </para> /// <para> - /// <seealso cref="CookieBuilder.SameSite"/> determines if the browser should allow the cookie to be attached to same-site or cross-site requests. - /// The default is Lax, which means the cookie is only allowed to be attached to cross-site requests using safe HTTP methods and same-site requests. + /// <see cref="CookieBuilder.SameSite"/> determines if the browser should allow the cookie to be attached to same-site or cross-site requests. + /// The default is <c>Lax</c>, which means the cookie is only allowed to be attached to cross-site requests using safe HTTP methods and same-site requests. /// </para> /// <para> - /// <seealso cref="CookieBuilder.HttpOnly"/> determines if the browser should allow the cookie to be accessed by client-side javascript. + /// <see cref="CookieBuilder.HttpOnly"/> determines if the browser should allow the cookie to be accessed by client-side javascript. /// The default is true, which means the cookie will only be passed to http requests and is not made available to script on the page. /// </para> /// <para> - /// <seealso cref="CookieBuilder.Expiration"/> is currently ignored. Use <see cref="ExpireTimeSpan"/> to control lifetime of cookie authentication. + /// <see cref="CookieBuilder.Expiration"/> is currently ignored. Use <see cref="ExpireTimeSpan"/> to control lifetime of cookie authentication. /// </para> /// </remarks> public CookieBuilder Cookie @@ -81,8 +81,8 @@ namespace Microsoft.AspNetCore.Authentication.Cookies /// <summary> /// The LoginPath property is used by the handler for the redirection target when handling ChallengeAsync. - /// The current url which is added to the LoginPath as a query string parameter named by the ReturnUrlParameter. - /// Once a request to the LoginPath grants a new SignIn identity, the ReturnUrlParameter value is used to redirect + /// The current url which is added to the LoginPath as a query string parameter named by the ReturnUrlParameter. + /// Once a request to the LoginPath grants a new SignIn identity, the ReturnUrlParameter value is used to redirect /// the browser back to the original url. /// </summary> public PathString LoginPath { get; set; } @@ -99,7 +99,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies /// <summary> /// The ReturnUrlParameter determines the name of the query string parameter which is appended by the handler - /// when during a Challenge. This is also the query string parameter looked for when a request arrives on the + /// when during a Challenge. This is also the query string parameter looked for when a request arrives on the /// login path or logout path, in order to return to the original url after the action is performed. /// </summary> public string ReturnUrlParameter { get; set; } @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies /// even if it is passed to the server after the browser should have purged it. /// </para> /// <para> - /// This is separate from the value of <seealso cref="CookieOptions.Expires"/>, which specifies + /// This is separate from the value of <see cref="CookieOptions.Expires"/>, which specifies /// how long the browser will keep the cookie. /// </para> /// </summary> diff --git a/src/Security/Authentication/Core/ref/Microsoft.AspNetCore.Authentication.netcoreapp.cs b/src/Security/Authentication/Core/ref/Microsoft.AspNetCore.Authentication.netcoreapp.cs index ac15a1853d..1a1d21a774 100644 --- a/src/Security/Authentication/Core/ref/Microsoft.AspNetCore.Authentication.netcoreapp.cs +++ b/src/Security/Authentication/Core/ref/Microsoft.AspNetCore.Authentication.netcoreapp.cs @@ -6,15 +6,15 @@ namespace Microsoft.AspNetCore.Authentication public partial class AccessDeniedContext : Microsoft.AspNetCore.Authentication.HandleRequestContext<Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions> { public AccessDeniedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions)) { } - public Microsoft.AspNetCore.Http.PathString AccessDeniedPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrlParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.PathString AccessDeniedPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrl { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrlParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class AuthenticationBuilder { public AuthenticationBuilder(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } - public virtual Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual Microsoft.AspNetCore.Authentication.AuthenticationBuilder AddPolicyScheme(string authenticationScheme, string displayName, System.Action<Microsoft.AspNetCore.Authentication.PolicySchemeOptions> configureOptions) { throw null; } public virtual Microsoft.AspNetCore.Authentication.AuthenticationBuilder AddRemoteScheme<TOptions, THandler>(string authenticationScheme, string displayName, System.Action<TOptions> configureOptions) where TOptions : Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions, new() where THandler : Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions> { throw null; } public virtual Microsoft.AspNetCore.Authentication.AuthenticationBuilder AddScheme<TOptions, THandler>(string authenticationScheme, System.Action<TOptions> configureOptions) where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions, new() where THandler : Microsoft.AspNetCore.Authentication.AuthenticationHandler<TOptions> { throw null; } @@ -24,19 +24,19 @@ namespace Microsoft.AspNetCore.Authentication { protected AuthenticationHandler(Microsoft.Extensions.Options.IOptionsMonitor<TOptions> options, Microsoft.Extensions.Logging.ILoggerFactory logger, System.Text.Encodings.Web.UrlEncoder encoder, Microsoft.AspNetCore.Authentication.ISystemClock clock) { } protected virtual string ClaimsIssuer { get { throw null; } } - protected Microsoft.AspNetCore.Authentication.ISystemClock Clock { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected Microsoft.AspNetCore.Authentication.ISystemClock Clock { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected string CurrentUri { get { throw null; } } - protected virtual object Events { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public TOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected Microsoft.Extensions.Options.IOptionsMonitor<TOptions> OptionsMonitor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected virtual object Events { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + protected Microsoft.Extensions.Logging.ILogger Logger { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public TOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected Microsoft.Extensions.Options.IOptionsMonitor<TOptions> OptionsMonitor { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected Microsoft.AspNetCore.Http.PathString OriginalPath { get { throw null; } } protected Microsoft.AspNetCore.Http.PathString OriginalPathBase { get { throw null; } } protected Microsoft.AspNetCore.Http.HttpRequest Request { get { throw null; } } protected Microsoft.AspNetCore.Http.HttpResponse Response { get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationScheme Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - protected System.Text.Encodings.Web.UrlEncoder UrlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.AuthenticationScheme Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + protected System.Text.Encodings.Web.UrlEncoder UrlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task<Microsoft.AspNetCore.Authentication.AuthenticateResult> AuthenticateAsync() { throw null; } protected string BuildRedirectUri(string targetPath) { throw null; } @@ -61,23 +61,23 @@ namespace Microsoft.AspNetCore.Authentication public partial class AuthenticationMiddleware { public AuthenticationMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next, Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider schemes) { } - public Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider Schemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider Schemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task Invoke(Microsoft.AspNetCore.Http.HttpContext context) { throw null; } } public partial class AuthenticationSchemeOptions { public AuthenticationSchemeOptions() { } - public string ClaimsIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public object Events { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Type EventsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardAuthenticate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardChallenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardDefault { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Http.HttpContext, string> ForwardDefaultSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardForbid { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardSignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ForwardSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ClaimsIssuer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public object Events { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Type EventsType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardAuthenticate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardChallenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardDefault { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Http.HttpContext, string> ForwardDefaultSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardForbid { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardSignIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ForwardSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void Validate() { } public virtual void Validate(string scheme) { } } @@ -89,24 +89,24 @@ namespace Microsoft.AspNetCore.Authentication public abstract partial class BaseContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { protected BaseContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options) { } - public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public TOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public TOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Http.HttpRequest Request { get { throw null; } } public Microsoft.AspNetCore.Http.HttpResponse Response { get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationScheme Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.AuthenticationScheme Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class HandleRequestContext<TOptions> : Microsoft.AspNetCore.Authentication.BaseContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { protected HandleRequestContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(TOptions)) { } - public Microsoft.AspNetCore.Authentication.HandleRequestResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public Microsoft.AspNetCore.Authentication.HandleRequestResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public void HandleResponse() { } public void SkipHandler() { } } public partial class HandleRequestResult : Microsoft.AspNetCore.Authentication.AuthenticateResult { public HandleRequestResult() { } - public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool Skipped { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool Skipped { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static new Microsoft.AspNetCore.Authentication.HandleRequestResult Fail(System.Exception failure) { throw null; } public static new Microsoft.AspNetCore.Authentication.HandleRequestResult Fail(System.Exception failure, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { throw null; } public static new Microsoft.AspNetCore.Authentication.HandleRequestResult Fail(string failureMessage) { throw null; } @@ -152,12 +152,12 @@ namespace Microsoft.AspNetCore.Authentication public abstract partial class PrincipalContext<TOptions> : Microsoft.AspNetCore.Authentication.PropertiesContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { protected PrincipalContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(TOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public virtual System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class PropertiesContext<TOptions> : Microsoft.AspNetCore.Authentication.BaseContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { protected PropertiesContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(TOptions)) { } - public virtual Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]protected set { } } + public virtual Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } } public partial class PropertiesDataFormat : Microsoft.AspNetCore.Authentication.SecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> { @@ -166,7 +166,7 @@ namespace Microsoft.AspNetCore.Authentication public partial class PropertiesSerializer : Microsoft.AspNetCore.Authentication.IDataSerializer<Microsoft.AspNetCore.Authentication.AuthenticationProperties> { public PropertiesSerializer() { } - public static Microsoft.AspNetCore.Authentication.PropertiesSerializer Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public static Microsoft.AspNetCore.Authentication.PropertiesSerializer Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual Microsoft.AspNetCore.Authentication.AuthenticationProperties Deserialize(byte[] data) { throw null; } public virtual Microsoft.AspNetCore.Authentication.AuthenticationProperties Read(System.IO.BinaryReader reader) { throw null; } public virtual byte[] Serialize(Microsoft.AspNetCore.Authentication.AuthenticationProperties model) { throw null; } @@ -175,13 +175,13 @@ namespace Microsoft.AspNetCore.Authentication public partial class RedirectContext<TOptions> : Microsoft.AspNetCore.Authentication.PropertiesContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { public RedirectContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, string redirectUri) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(TOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public string RedirectUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string RedirectUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public abstract partial class RemoteAuthenticationContext<TOptions> : Microsoft.AspNetCore.Authentication.HandleRequestContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { protected RemoteAuthenticationContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(TOptions)) { } - public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Fail(System.Exception failure) { } public void Fail(string failureMessage) { } public void Success() { } @@ -189,9 +189,9 @@ namespace Microsoft.AspNetCore.Authentication public partial class RemoteAuthenticationEvents { public RemoteAuthenticationEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.AccessDeniedContext, System.Threading.Tasks.Task> OnAccessDenied { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.RemoteFailureContext, System.Threading.Tasks.Task> OnRemoteFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.TicketReceivedContext, System.Threading.Tasks.Task> OnTicketReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.AccessDeniedContext, System.Threading.Tasks.Task> OnAccessDenied { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RemoteFailureContext, System.Threading.Tasks.Task> OnRemoteFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.TicketReceivedContext, System.Threading.Tasks.Task> OnTicketReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task AccessDenied(Microsoft.AspNetCore.Authentication.AccessDeniedContext context) { throw null; } public virtual System.Threading.Tasks.Task RemoteFailure(Microsoft.AspNetCore.Authentication.RemoteFailureContext context) { throw null; } public virtual System.Threading.Tasks.Task TicketReceived(Microsoft.AspNetCore.Authentication.TicketReceivedContext context) { throw null; } @@ -217,39 +217,39 @@ namespace Microsoft.AspNetCore.Authentication public partial class RemoteAuthenticationOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { public RemoteAuthenticationOptions() { } - public Microsoft.AspNetCore.Http.PathString AccessDeniedPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.Http.HttpClient Backchannel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.Http.HttpMessageHandler BackchannelHttpHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan BackchannelTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString CallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.PathString AccessDeniedPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.Http.HttpClient Backchannel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.Http.HttpMessageHandler BackchannelHttpHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan BackchannelTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString CallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.CookieBuilder CorrelationCookie { get { throw null; } set { } } - public Microsoft.AspNetCore.DataProtection.IDataProtectionProvider DataProtectionProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.DataProtection.IDataProtectionProvider DataProtectionProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.RemoteAuthenticationEvents Events { get { throw null; } set { } } - public System.TimeSpan RemoteAuthenticationTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ReturnUrlParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SaveTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignInScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan RemoteAuthenticationTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ReturnUrlParameter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SaveTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignInScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Validate() { } public override void Validate(string scheme) { } } public partial class RemoteFailureContext : Microsoft.AspNetCore.Authentication.HandleRequestContext<Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions> { public RemoteFailureContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions options, System.Exception failure) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions)) { } - public System.Exception Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RequestPathBaseCookieBuilder : Microsoft.AspNetCore.Http.CookieBuilder { public RequestPathBaseCookieBuilder() { } - protected virtual string AdditionalPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected virtual string AdditionalPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override Microsoft.AspNetCore.Http.CookieOptions Build(Microsoft.AspNetCore.Http.HttpContext context, System.DateTimeOffset expiresFrom) { throw null; } } public abstract partial class ResultContext<TOptions> : Microsoft.AspNetCore.Authentication.BaseContext<TOptions> where TOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { protected ResultContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, TOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(TOptions)) { } - public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Claims.ClaimsPrincipal Principal { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { get { throw null; } set { } } - public Microsoft.AspNetCore.Authentication.AuthenticateResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.AuthenticateResult Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void Fail(System.Exception failure) { } public void Fail(string failureMessage) { } public void NoResult() { } @@ -287,12 +287,12 @@ namespace Microsoft.AspNetCore.Authentication public partial class TicketReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions> { public TicketReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationTicket ticket) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public string ReturnUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ReturnUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TicketSerializer : Microsoft.AspNetCore.Authentication.IDataSerializer<Microsoft.AspNetCore.Authentication.AuthenticationTicket> { public TicketSerializer() { } - public static Microsoft.AspNetCore.Authentication.TicketSerializer Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public static Microsoft.AspNetCore.Authentication.TicketSerializer Default { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual Microsoft.AspNetCore.Authentication.AuthenticationTicket Deserialize(byte[] data) { throw null; } public virtual Microsoft.AspNetCore.Authentication.AuthenticationTicket Read(System.IO.BinaryReader reader) { throw null; } protected virtual System.Security.Claims.Claim ReadClaim(System.IO.BinaryReader reader, System.Security.Claims.ClaimsIdentity identity) { throw null; } diff --git a/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs b/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs index a8975f11a0..b4d4cbef88 100644 --- a/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs +++ b/src/Security/Authentication/Core/src/RemoteAuthenticationHandler.cs @@ -18,8 +18,6 @@ namespace Microsoft.AspNetCore.Authentication private const string CorrelationMarker = "N"; private const string AuthSchemeKey = ".AuthScheme"; - private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); - protected string SignInScheme => Options.SignInScheme; /// <summary> @@ -194,7 +192,7 @@ namespace Microsoft.AspNetCore.Authentication } var bytes = new byte[32]; - CryptoRandom.GetBytes(bytes); + RandomNumberGenerator.Fill(bytes); var correlationId = Base64UrlTextEncoder.Encode(bytes); var cookieOptions = Options.CorrelationCookie.Build(Context, Clock.UtcNow); diff --git a/src/Security/Authentication/Facebook/ref/Microsoft.AspNetCore.Authentication.Facebook.netcoreapp.cs b/src/Security/Authentication/Facebook/ref/Microsoft.AspNetCore.Authentication.Facebook.netcoreapp.cs index 32da964494..317640bd93 100644 --- a/src/Security/Authentication/Facebook/ref/Microsoft.AspNetCore.Authentication.Facebook.netcoreapp.cs +++ b/src/Security/Authentication/Facebook/ref/Microsoft.AspNetCore.Authentication.Facebook.netcoreapp.cs @@ -24,8 +24,8 @@ namespace Microsoft.AspNetCore.Authentication.Facebook public FacebookOptions() { } public string AppId { get { throw null; } set { } } public string AppSecret { get { throw null; } set { } } - public System.Collections.Generic.ICollection<string> Fields { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool SendAppSecretProof { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.ICollection<string> Fields { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool SendAppSecretProof { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Validate() { } } } diff --git a/src/Security/Authentication/Google/ref/Microsoft.AspNetCore.Authentication.Google.netcoreapp.cs b/src/Security/Authentication/Google/ref/Microsoft.AspNetCore.Authentication.Google.netcoreapp.cs index 1346c4378a..18165e7b56 100644 --- a/src/Security/Authentication/Google/ref/Microsoft.AspNetCore.Authentication.Google.netcoreapp.cs +++ b/src/Security/Authentication/Google/ref/Microsoft.AspNetCore.Authentication.Google.netcoreapp.cs @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Authentication.Google public partial class GoogleOptions : Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions { public GoogleOptions() { } - public string AccessType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AccessType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Security/Authentication/JwtBearer/ref/Microsoft.AspNetCore.Authentication.JwtBearer.netcoreapp.cs b/src/Security/Authentication/JwtBearer/ref/Microsoft.AspNetCore.Authentication.JwtBearer.netcoreapp.cs index 8864d2ebad..27d30e350b 100644 --- a/src/Security/Authentication/JwtBearer/ref/Microsoft.AspNetCore.Authentication.JwtBearer.netcoreapp.cs +++ b/src/Security/Authentication/JwtBearer/ref/Microsoft.AspNetCore.Authentication.JwtBearer.netcoreapp.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer public partial class AuthenticationFailedContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> { public AuthenticationFailedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions)) { } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ForbiddenContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> { @@ -15,11 +15,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer public partial class JwtBearerChallengeContext : Microsoft.AspNetCore.Authentication.PropertiesContext<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> { public JwtBearerChallengeContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public System.Exception AuthenticateFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ErrorDescription { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ErrorUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Exception AuthenticateFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ErrorDescription { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ErrorUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void HandleResponse() { } } public static partial class JwtBearerDefaults @@ -29,11 +29,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer public partial class JwtBearerEvents { public JwtBearerEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerChallengeContext, System.Threading.Tasks.Task> OnChallenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.ForbiddenContext, System.Threading.Tasks.Task> OnForbidden { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.MessageReceivedContext, System.Threading.Tasks.Task> OnMessageReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.TokenValidatedContext, System.Threading.Tasks.Task> OnTokenValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerChallengeContext, System.Threading.Tasks.Task> OnChallenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.ForbiddenContext, System.Threading.Tasks.Task> OnForbidden { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.MessageReceivedContext, System.Threading.Tasks.Task> OnMessageReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.JwtBearer.TokenValidatedContext, System.Threading.Tasks.Task> OnTokenValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task AuthenticationFailed(Microsoft.AspNetCore.Authentication.JwtBearer.AuthenticationFailedContext context) { throw null; } public virtual System.Threading.Tasks.Task Challenge(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerChallengeContext context) { throw null; } public virtual System.Threading.Tasks.Task Forbidden(Microsoft.AspNetCore.Authentication.JwtBearer.ForbiddenContext context) { throw null; } @@ -54,21 +54,23 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer public partial class JwtBearerOptions : Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions { public JwtBearerOptions() { } - public string Audience { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.Http.HttpMessageHandler BackchannelHttpHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan BackchannelTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Challenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.IConfigurationManager<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration> ConfigurationManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Audience { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan AutomaticRefreshInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.Http.HttpMessageHandler BackchannelHttpHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan BackchannelTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Challenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.IConfigurationManager<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration> ConfigurationManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents Events { get { throw null; } set { } } - public bool IncludeErrorDetails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string MetadataAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RefreshOnIssuerKeyNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireHttpsMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SaveToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<Microsoft.IdentityModel.Tokens.ISecurityTokenValidator> SecurityTokenValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.IdentityModel.Tokens.TokenValidationParameters TokenValidationParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool IncludeErrorDetails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string MetadataAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan RefreshInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RefreshOnIssuerKeyNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireHttpsMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SaveToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<Microsoft.IdentityModel.Tokens.ISecurityTokenValidator> SecurityTokenValidators { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.IdentityModel.Tokens.TokenValidationParameters TokenValidationParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class JwtBearerPostConfigureOptions : Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> { @@ -78,12 +80,12 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer public partial class MessageReceivedContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> { public MessageReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions)) { } - public string Token { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Token { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenValidatedContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions> { public TokenValidatedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions)) { } - public Microsoft.IdentityModel.Tokens.SecurityToken SecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Tokens.SecurityToken SecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Security/Authentication/JwtBearer/samples/JwtBearerSample/Startup.cs b/src/Security/Authentication/JwtBearer/samples/JwtBearerSample/Startup.cs index 65a3e40f7a..4f8831b29e 100644 --- a/src/Security/Authentication/JwtBearer/samples/JwtBearerSample/Startup.cs +++ b/src/Security/Authentication/JwtBearer/samples/JwtBearerSample/Startup.cs @@ -78,7 +78,7 @@ namespace JwtBearerSample todoApp.Run(async context => { var response = context.Response; - if (context.Request.Method.Equals("POST", System.StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsPost(context.Request.Method)) { var reader = new StreamReader(context.Request.Body); var body = await reader.ReadToEndAsync(); diff --git a/src/Security/Authentication/JwtBearer/src/JwtBearerOptions.cs b/src/Security/Authentication/JwtBearer/src/JwtBearerOptions.cs index f0e7cbc5de..758added5b 100644 --- a/src/Security/Authentication/JwtBearer/src/JwtBearerOptions.cs +++ b/src/Security/Authentication/JwtBearer/src/JwtBearerOptions.cs @@ -111,5 +111,15 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer /// from returning an error and an error_description in the WWW-Authenticate header. /// </summary> public bool IncludeErrorDetails { get; set; } = true; + + /// <summary> + /// 1 day is the default time interval that afterwards, <see cref="ConfigurationManager" /> will obtain new configuration. + /// </summary> + public TimeSpan AutomaticRefreshInterval { get; set; } = ConfigurationManager<OpenIdConnectConfiguration>.DefaultAutomaticRefreshInterval; + + /// <summary> + /// The minimum time between <see cref="ConfigurationManager" /> retrievals, in the event that a retrieval failed, or that a refresh was explicitly requested. 30 seconds is the default. + /// </summary> + public TimeSpan RefreshInterval { get; set; } = ConfigurationManager<OpenIdConnectConfiguration>.DefaultRefreshInterval; } } diff --git a/src/Security/Authentication/JwtBearer/src/JwtBearerPostConfigureOptions.cs b/src/Security/Authentication/JwtBearer/src/JwtBearerPostConfigureOptions.cs index 8829bfac0f..f52cfb2353 100644 --- a/src/Security/Authentication/JwtBearer/src/JwtBearerPostConfigureOptions.cs +++ b/src/Security/Authentication/JwtBearer/src/JwtBearerPostConfigureOptions.cs @@ -55,7 +55,11 @@ namespace Microsoft.AspNetCore.Authentication.JwtBearer httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(options.MetadataAddress, new OpenIdConnectConfigurationRetriever(), - new HttpDocumentRetriever(httpClient) { RequireHttps = options.RequireHttpsMetadata }); + new HttpDocumentRetriever(httpClient) { RequireHttps = options.RequireHttpsMetadata }) + { + RefreshInterval = options.RefreshInterval, + AutomaticRefreshInterval = options.AutomaticRefreshInterval, + }; } } } diff --git a/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs b/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs index 6114b15394..043900b1aa 100644 --- a/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs +++ b/src/Security/Authentication/MicrosoftAccount/src/MicrosoftAccountHandler.cs @@ -20,8 +20,6 @@ namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount { public class MicrosoftAccountHandler : OAuthHandler<MicrosoftAccountOptions> { - private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); - public MicrosoftAccountHandler(IOptionsMonitor<MicrosoftAccountOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { } @@ -64,7 +62,7 @@ namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount if (Options.UsePkce) { var bytes = new byte[32]; - CryptoRandom.GetBytes(bytes); + RandomNumberGenerator.Fill(bytes); var codeVerifier = Base64UrlTextEncoder.Encode(bytes); // Store this for use during the code redemption. diff --git a/src/Security/Authentication/MicrosoftAccount/src/MicrosoftChallengeProperties.cs b/src/Security/Authentication/MicrosoftAccount/src/MicrosoftChallengeProperties.cs index 8625e3f093..4e9737b509 100644 --- a/src/Security/Authentication/MicrosoftAccount/src/MicrosoftChallengeProperties.cs +++ b/src/Security/Authentication/MicrosoftAccount/src/MicrosoftChallengeProperties.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Authentication.OAuth; namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount { /// <summary> - /// See https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code for reference + /// See https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow#request-an-authorization-code for reference /// </summary> public class MicrosoftChallengeProperties : OAuthChallengeProperties { diff --git a/src/Security/Authentication/Negotiate/ref/Microsoft.AspNetCore.Authentication.Negotiate.netcoreapp.cs b/src/Security/Authentication/Negotiate/ref/Microsoft.AspNetCore.Authentication.Negotiate.netcoreapp.cs index 5821e59a77..3dc0133423 100644 --- a/src/Security/Authentication/Negotiate/ref/Microsoft.AspNetCore.Authentication.Negotiate.netcoreapp.cs +++ b/src/Security/Authentication/Negotiate/ref/Microsoft.AspNetCore.Authentication.Negotiate.netcoreapp.cs @@ -10,12 +10,12 @@ namespace Microsoft.AspNetCore.Authentication.Negotiate public partial class AuthenticationFailedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions> { public AuthenticationFailedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ChallengeContext : Microsoft.AspNetCore.Authentication.PropertiesContext<Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions> { public ChallengeContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void HandleResponse() { } } public static partial class NegotiateDefaults @@ -25,9 +25,9 @@ namespace Microsoft.AspNetCore.Authentication.Negotiate public partial class NegotiateEvents { public NegotiateEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.Negotiate.AuthenticatedContext, System.Threading.Tasks.Task> OnAuthenticated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Negotiate.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.Negotiate.ChallengeContext, System.Threading.Tasks.Task> OnChallenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Negotiate.AuthenticatedContext, System.Threading.Tasks.Task> OnAuthenticated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Negotiate.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Negotiate.ChallengeContext, System.Threading.Tasks.Task> OnChallenge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task Authenticated(Microsoft.AspNetCore.Authentication.Negotiate.AuthenticatedContext context) { throw null; } public virtual System.Threading.Tasks.Task AuthenticationFailed(Microsoft.AspNetCore.Authentication.Negotiate.AuthenticationFailedContext context) { throw null; } public virtual System.Threading.Tasks.Task Challenge(Microsoft.AspNetCore.Authentication.Negotiate.ChallengeContext context) { throw null; } @@ -48,8 +48,8 @@ namespace Microsoft.AspNetCore.Authentication.Negotiate { public NegotiateOptions() { } public new Microsoft.AspNetCore.Authentication.Negotiate.NegotiateEvents Events { get { throw null; } set { } } - public bool PersistKerberosCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool PersistNtlmCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool PersistKerberosCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool PersistNtlmCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class PostConfigureNegotiateOptions : Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.AspNetCore.Authentication.Negotiate.NegotiateOptions> { diff --git a/src/Security/Authentication/Negotiate/test/Negotiate.FunctionalTest/CrossMachineReadMe.md b/src/Security/Authentication/Negotiate/test/Negotiate.FunctionalTest/CrossMachineReadMe.md index e263a2c5f7..ec83949331 100644 --- a/src/Security/Authentication/Negotiate/test/Negotiate.FunctionalTest/CrossMachineReadMe.md +++ b/src/Security/Authentication/Negotiate/test/Negotiate.FunctionalTest/CrossMachineReadMe.md @@ -1,24 +1,24 @@ Cross Machine Tests -Kerberos can only be tested in a multi-machine environment. On localhost it always falls back to NTLM which has different requirements. Multi-machine is also neccisary for interop testing across OSs. Kerberos also requires domain controler SPN configuration so we can't test it on arbitrary test boxes. +Kerberos can only be tested in a multi-machine environment. On localhost it always falls back to NTLM which has different requirements. Multi-machine is also necessary for interop testing across OSs. Kerberos also requires domain controller SPN configuration so we can't test it on arbitrary test boxes. Test structure: - A remote test server with various endpoints with different authentication restrictions. -- A remote test client with endpoints that execute specific scenarios. The input for these endpoints is theory data. The output is either 200Ok, or a failure code and desciption. +- A remote test client with endpoints that execute specific scenarios. The input for these endpoints is theory data. The output is either 200Ok, or a failure code and description. - The CrossMachineTest class that drives the tests. It invokes the client app with the theory data and confirms the results. -We use these three components beceause it allows us to run the tests from a dev machine or CI agent that is not part of the dedicated test domain/environment. +We use these three components because it allows us to run the tests from a dev machine or CI agent that is not part of the dedicated test domain/environment. (Static) Environment Setup: - Warning, this environment can take a day to set up. That's why we want a static test environment that we can re-use. - Create a Windows server running DNS and Active Directory. Promote it to a domain controller. - Create an SPN on this machine for Windows -> Windows testing. `setspn -S "http/chrross-dc.crkerberos.com" -U administrator` - Future: Can we replace the domain controller with an AAD instance? We'd still want a second windows machine for Windows -> Windows testing, but AAD might be easier to configure. - - https://docs.microsoft.com/en-us/azure/active-directory-domain-services/active-directory-ds-getting-started - - https://docs.microsoft.com/en-us/azure/active-directory-domain-services/active-directory-ds-join-ubuntu-linux-vm - - https://docs.microsoft.com/en-us/azure/active-directory-domain-services/active-directory-ds-enable-kcd + - https://docs.microsoft.com/azure/active-directory-domain-services/active-directory-ds-getting-started + - https://docs.microsoft.com/azure/active-directory-domain-services/active-directory-ds-join-ubuntu-linux-vm + - https://docs.microsoft.com/azure/active-directory-domain-services/active-directory-ds-enable-kcd - Create another Windows machine and join it to the test domain. -- Create a Linux machine and joing it to the domain. Ubuntu 18.04 has been used in the past. +- Create a Linux machine and joining it to the domain. Ubuntu 18.04 has been used in the past. - https://www.safesquid.com/content-filtering/integrating-linux-host-windows-ad-kerberos-sso-authentication - Include an HTTP SPN diff --git a/src/Security/Authentication/OAuth/ref/Microsoft.AspNetCore.Authentication.OAuth.netcoreapp.cs b/src/Security/Authentication/OAuth/ref/Microsoft.AspNetCore.Authentication.OAuth.netcoreapp.cs index 73d5e441da..2301daf1ad 100644 --- a/src/Security/Authentication/OAuth/ref/Microsoft.AspNetCore.Authentication.OAuth.netcoreapp.cs +++ b/src/Security/Authentication/OAuth/ref/Microsoft.AspNetCore.Authentication.OAuth.netcoreapp.cs @@ -31,9 +31,9 @@ namespace Microsoft.AspNetCore.Authentication.OAuth public partial class OAuthCodeExchangeContext { public OAuthCodeExchangeContext(Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, string code, string redirectUri) { } - public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string RedirectUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Code { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string RedirectUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class OAuthConstants { @@ -46,13 +46,13 @@ namespace Microsoft.AspNetCore.Authentication.OAuth { public OAuthCreatingTicketContext(System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions options, System.Net.Http.HttpClient backchannel, Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse tokens, System.Text.Json.JsonElement user) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions)) { } public string AccessToken { get { throw null; } } - public System.Net.Http.HttpClient Backchannel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Net.Http.HttpClient Backchannel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.TimeSpan? ExpiresIn { get { throw null; } } public System.Security.Claims.ClaimsIdentity Identity { get { throw null; } } public string RefreshToken { get { throw null; } } - public Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse TokenResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse TokenResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string TokenType { get { throw null; } } - public System.Text.Json.JsonElement User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Text.Json.JsonElement User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public void RunClaimActions() { } public void RunClaimActions(System.Text.Json.JsonElement userData) { } } @@ -63,8 +63,8 @@ namespace Microsoft.AspNetCore.Authentication.OAuth public partial class OAuthEvents : Microsoft.AspNetCore.Authentication.RemoteAuthenticationEvents { public OAuthEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.OAuth.OAuthCreatingTicketContext, System.Threading.Tasks.Task> OnCreatingTicket { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions>, System.Threading.Tasks.Task> OnRedirectToAuthorizationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OAuth.OAuthCreatingTicketContext, System.Threading.Tasks.Task> OnCreatingTicket { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions>, System.Threading.Tasks.Task> OnRedirectToAuthorizationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task CreatingTicket(Microsoft.AspNetCore.Authentication.OAuth.OAuthCreatingTicketContext context) { throw null; } public virtual System.Threading.Tasks.Task RedirectToAuthorizationEndpoint(Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions> context) { throw null; } } @@ -89,27 +89,27 @@ namespace Microsoft.AspNetCore.Authentication.OAuth public partial class OAuthOptions : Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions { public OAuthOptions() { } - public string AuthorizationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimActionCollection ClaimActions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthorizationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimActionCollection ClaimActions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents Events { get { throw null; } set { } } - public System.Collections.Generic.ICollection<string> Scope { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string TokenEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool UsePkce { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UserInformationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.ICollection<string> Scope { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string TokenEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool UsePkce { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UserInformationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Validate() { } } public partial class OAuthTokenResponse : System.IDisposable { internal OAuthTokenResponse() { } - public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Exception Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ExpiresIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string RefreshToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Text.Json.JsonDocument Response { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string TokenType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Exception Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ExpiresIn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RefreshToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Text.Json.JsonDocument Response { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string TokenType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void Dispose() { } public static Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse Failed(System.Exception error) { throw null; } public static Microsoft.AspNetCore.Authentication.OAuth.OAuthTokenResponse Success(System.Text.Json.JsonDocument response) { throw null; } @@ -120,8 +120,8 @@ namespace Microsoft.AspNetCore.Authentication.OAuth.Claims public abstract partial class ClaimAction { public ClaimAction(string claimType, string valueType) { } - public string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ValueType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ValueType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public abstract void Run(System.Text.Json.JsonElement userData, System.Security.Claims.ClaimsIdentity identity, string issuer); } public partial class ClaimActionCollection : System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction>, System.Collections.IEnumerable @@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth.Claims public partial class CustomJsonClaimAction : Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction { public CustomJsonClaimAction(string claimType, string valueType, System.Func<System.Text.Json.JsonElement, string> resolver) : base (default(string), default(string)) { } - public System.Func<System.Text.Json.JsonElement, string> Resolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Func<System.Text.Json.JsonElement, string> Resolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override void Run(System.Text.Json.JsonElement userData, System.Security.Claims.ClaimsIdentity identity, string issuer) { } } public partial class DeleteClaimAction : Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction @@ -147,13 +147,13 @@ namespace Microsoft.AspNetCore.Authentication.OAuth.Claims public partial class JsonKeyClaimAction : Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction { public JsonKeyClaimAction(string claimType, string valueType, string jsonKey) : base (default(string), default(string)) { } - public string JsonKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string JsonKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override void Run(System.Text.Json.JsonElement userData, System.Security.Claims.ClaimsIdentity identity, string issuer) { } } public partial class JsonSubKeyClaimAction : Microsoft.AspNetCore.Authentication.OAuth.Claims.JsonKeyClaimAction { public JsonSubKeyClaimAction(string claimType, string valueType, string jsonKey, string subKey) : base (default(string), default(string), default(string)) { } - public string SubKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string SubKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override void Run(System.Text.Json.JsonElement userData, System.Security.Claims.ClaimsIdentity identity, string issuer) { } } public partial class MapAllClaimsAction : Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction diff --git a/src/Security/Authentication/OAuth/src/OAuthHandler.cs b/src/Security/Authentication/OAuth/src/OAuthHandler.cs index a6bfbbc550..29ef3036f8 100644 --- a/src/Security/Authentication/OAuth/src/OAuthHandler.cs +++ b/src/Security/Authentication/OAuth/src/OAuthHandler.cs @@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Authentication.OAuth { public class OAuthHandler<TOptions> : RemoteAuthenticationHandler<TOptions> where TOptions : OAuthOptions, new() { - private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); protected HttpClient Backchannel => Options.Backchannel; /// <summary> @@ -274,7 +273,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth if (Options.UsePkce) { var bytes = new byte[32]; - CryptoRandom.GetBytes(bytes); + RandomNumberGenerator.Fill(bytes); var codeVerifier = Base64UrlTextEncoder.Encode(bytes); // Store this for use during the code redemption. diff --git a/src/Security/Authentication/OpenIdConnect/ref/Microsoft.AspNetCore.Authentication.OpenIdConnect.netcoreapp.cs b/src/Security/Authentication/OpenIdConnect/ref/Microsoft.AspNetCore.Authentication.OpenIdConnect.netcoreapp.cs index 998956d2ed..395acef099 100644 --- a/src/Security/Authentication/OpenIdConnect/ref/Microsoft.AspNetCore.Authentication.OpenIdConnect.netcoreapp.cs +++ b/src/Security/Authentication/OpenIdConnect/ref/Microsoft.AspNetCore.Authentication.OpenIdConnect.netcoreapp.cs @@ -14,18 +14,18 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect public partial class AuthenticationFailedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public AuthenticationFailedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class AuthorizationCodeReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public AuthorizationCodeReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public System.Net.Http.HttpClient Backchannel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Net.Http.HttpClient Backchannel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public bool HandledCodeRedemption { get { throw null; } } - public System.IdentityModel.Tokens.Jwt.JwtSecurityToken JwtSecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IdentityModel.Tokens.Jwt.JwtSecurityToken JwtSecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointRequest { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void HandleCodeRedemption() { } public void HandleCodeRedemption(Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage tokenEndpointResponse) { } public void HandleCodeRedemption(string accessToken, string idToken) { } @@ -33,8 +33,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect public partial class MessageReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public MessageReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Token { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Token { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class OpenIdConnectChallengeProperties : Microsoft.AspNetCore.Authentication.OAuth.OAuthChallengeProperties { @@ -58,16 +58,16 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect public partial class OpenIdConnectEvents : Microsoft.AspNetCore.Authentication.RemoteAuthenticationEvents { public OpenIdConnectEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthorizationCodeReceivedContext, System.Threading.Tasks.Task> OnAuthorizationCodeReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.MessageReceivedContext, System.Threading.Tasks.Task> OnMessageReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext, System.Threading.Tasks.Task> OnRedirectToIdentityProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext, System.Threading.Tasks.Task> OnRedirectToIdentityProviderForSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RemoteSignOutContext, System.Threading.Tasks.Task> OnRemoteSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RemoteSignOutContext, System.Threading.Tasks.Task> OnSignedOutCallbackRedirect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenResponseReceivedContext, System.Threading.Tasks.Task> OnTokenResponseReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext, System.Threading.Tasks.Task> OnTokenValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.UserInformationReceivedContext, System.Threading.Tasks.Task> OnUserInformationReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthorizationCodeReceivedContext, System.Threading.Tasks.Task> OnAuthorizationCodeReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.MessageReceivedContext, System.Threading.Tasks.Task> OnMessageReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext, System.Threading.Tasks.Task> OnRedirectToIdentityProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RedirectContext, System.Threading.Tasks.Task> OnRedirectToIdentityProviderForSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RemoteSignOutContext, System.Threading.Tasks.Task> OnRemoteSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.RemoteSignOutContext, System.Threading.Tasks.Task> OnSignedOutCallbackRedirect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenResponseReceivedContext, System.Threading.Tasks.Task> OnTokenResponseReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.TokenValidatedContext, System.Threading.Tasks.Task> OnTokenValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.OpenIdConnect.UserInformationReceivedContext, System.Threading.Tasks.Task> OnUserInformationReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task AuthenticationFailed(Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthenticationFailedContext context) { throw null; } public virtual System.Threading.Tasks.Task AuthorizationCodeReceived(Microsoft.AspNetCore.Authentication.OpenIdConnect.AuthorizationCodeReceivedContext context) { throw null; } public virtual System.Threading.Tasks.Task MessageReceived(Microsoft.AspNetCore.Authentication.OpenIdConnect.MessageReceivedContext context) { throw null; } @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect public OpenIdConnectHandler(Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> options, Microsoft.Extensions.Logging.ILoggerFactory logger, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, System.Text.Encodings.Web.UrlEncoder encoder, Microsoft.AspNetCore.Authentication.ISystemClock clock) : base (default(Microsoft.Extensions.Options.IOptionsMonitor<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions>), default(Microsoft.Extensions.Logging.ILoggerFactory), default(System.Text.Encodings.Web.UrlEncoder), default(Microsoft.AspNetCore.Authentication.ISystemClock)) { } protected System.Net.Http.HttpClient Backchannel { get { throw null; } } protected new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents Events { get { throw null; } set { } } - protected System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + protected System.Text.Encodings.Web.HtmlEncoder HtmlEncoder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task<object> CreateEventsAsync() { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] protected virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Authentication.HandleRequestResult> GetUserInformationAsync(Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage message, System.IdentityModel.Tokens.Jwt.JwtSecurityToken jwt, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) { throw null; } @@ -105,38 +105,40 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect public partial class OpenIdConnectOptions : Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions { public OpenIdConnectOptions() { } - public Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectRedirectBehavior AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimActionCollection ClaimActions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.IConfigurationManager<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration> ConfigurationManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool DisableTelemetry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectRedirectBehavior AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Authority { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan AutomaticRefreshInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimActionCollection ClaimActions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ClientId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ClientSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.IConfigurationManager<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration> ConfigurationManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool DisableTelemetry { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents Events { get { throw null; } set { } } - public bool GetClaimsFromUserInfoEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string MetadataAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool GetClaimsFromUserInfoEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string MetadataAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.CookieBuilder NonceCookie { get { throw null; } set { } } - public string Prompt { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolValidator ProtocolValidator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RefreshOnIssuerKeyNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString RemoteSignOutPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireHttpsMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ResponseMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ResponseType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.ICollection<string> Scope { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.IdentityModel.Tokens.ISecurityTokenValidator SecurityTokenValidator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString SignedOutCallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignedOutRedirectUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignOutScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SkipUnrecognizedRequests { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.ISecureDataFormat<string> StringDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Tokens.TokenValidationParameters TokenValidationParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool UsePkce { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool UseTokenLifetime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Prompt { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolValidator ProtocolValidator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan RefreshInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RefreshOnIssuerKeyNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString RemoteSignOutPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireHttpsMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ResponseMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ResponseType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.ICollection<string> Scope { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.IdentityModel.Tokens.ISecurityTokenValidator SecurityTokenValidator { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString SignedOutCallbackPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignedOutRedirectUri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignOutScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SkipUnrecognizedRequests { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.ISecureDataFormat<string> StringDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Tokens.TokenValidationParameters TokenValidationParameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool UsePkce { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool UseTokenLifetime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Validate() { } } public partial class OpenIdConnectPostConfigureOptions : Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> @@ -152,34 +154,34 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect public partial class RedirectContext : Microsoft.AspNetCore.Authentication.PropertiesContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public RedirectContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void HandleResponse() { } } public partial class RemoteSignOutContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public RemoteSignOutContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage message) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenResponseReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public TokenResponseReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, System.Security.Claims.ClaimsPrincipal user, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class TokenValidatedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public TokenValidatedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public string Nonce { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.IdentityModel.Tokens.Jwt.JwtSecurityToken SecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Nonce { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.IdentityModel.Tokens.Jwt.JwtSecurityToken SecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage TokenEndpointResponse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class UserInformationReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions> { public UserInformationReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions options, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Text.Json.JsonDocument User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Text.Json.JsonDocument User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Authentication.OpenIdConnect.Claims diff --git a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs index 65ad366a50..e1dc65df66 100644 --- a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs +++ b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectHandler.cs @@ -34,8 +34,6 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect private const string NonceProperty = "N"; private const string HeaderValueEpocDate = "Thu, 01 Jan 1970 00:00:00 GMT"; - private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create(); - private OpenIdConnectConfiguration _configuration; protected HttpClient Backchannel => Options.Backchannel; @@ -78,13 +76,13 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect { OpenIdConnectMessage message = null; - if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsGet(Request.Method)) { message = new OpenIdConnectMessage(Request.Query.Select(pair => new KeyValuePair<string, string[]>(pair.Key, pair.Value))); } // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. - else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) + else if (HttpMethods.IsPost(Request.Method) && !string.IsNullOrEmpty(Request.ContentType) // May have media/type; charset=utf-8, allow partial match. && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) @@ -371,7 +369,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect if (Options.UsePkce && Options.ResponseType == OpenIdConnectResponseType.Code) { var bytes = new byte[32]; - CryptoRandom.GetBytes(bytes); + RandomNumberGenerator.Fill(bytes); var codeVerifier = Base64UrlTextEncoder.Encode(bytes); // Store this for use during the code redemption. See RunAuthorizationCodeReceivedEventAsync. @@ -482,7 +480,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect OpenIdConnectMessage authorizationResponse = null; - if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsGet(Request.Method)) { authorizationResponse = new OpenIdConnectMessage(Request.Query.Select(pair => new KeyValuePair<string, string[]>(pair.Key, pair.Value))); @@ -501,7 +499,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect } } // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. - else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) + else if (HttpMethods.IsPost(Request.Method) && !string.IsNullOrEmpty(Request.ContentType) // May have media/type; charset=utf-8, allow partial match. && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) diff --git a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs index 7e3366bada..1b86c81901 100644 --- a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs +++ b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs @@ -288,7 +288,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect /// cookie gets added to the response. /// </summary> /// <remarks> - /// The value of <see cref="CookieBuilder.Name"/> is treated as the prefix to the cookie name, and defaults to <seealso cref="OpenIdConnectDefaults.CookieNoncePrefix"/>. + /// The value of <see cref="CookieBuilder.Name"/> is treated as the prefix to the cookie name, and defaults to <see cref="OpenIdConnectDefaults.CookieNoncePrefix"/>. /// </remarks> public CookieBuilder NonceCookie { @@ -327,5 +327,15 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect return cookieOptions; } } + + /// <summary> + /// 1 day is the default time interval that afterwards, <see cref="ConfigurationManager" /> will obtain new configuration. + /// </summary> + public TimeSpan AutomaticRefreshInterval { get; set; } = ConfigurationManager<OpenIdConnectConfiguration>.DefaultAutomaticRefreshInterval; + + /// <summary> + /// The minimum time between <see cref="ConfigurationManager" /> retrievals, in the event that a retrieval failed, or that a refresh was explicitly requested. 30 seconds is the default. + /// </summary> + public TimeSpan RefreshInterval { get; set; } = ConfigurationManager<OpenIdConnectConfiguration>.DefaultRefreshInterval; } } diff --git a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectPostConfigureOptions.cs b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectPostConfigureOptions.cs index b79f1d1edf..f1a39d7081 100644 --- a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectPostConfigureOptions.cs +++ b/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectPostConfigureOptions.cs @@ -93,7 +93,11 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect } options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(options.MetadataAddress, new OpenIdConnectConfigurationRetriever(), - new HttpDocumentRetriever(options.Backchannel) { RequireHttps = options.RequireHttpsMetadata }); + new HttpDocumentRetriever(options.Backchannel) { RequireHttps = options.RequireHttpsMetadata }) + { + RefreshInterval = options.RefreshInterval, + AutomaticRefreshInterval = options.AutomaticRefreshInterval, + }; } } } diff --git a/src/Security/Authentication/Twitter/ref/Microsoft.AspNetCore.Authentication.Twitter.netcoreapp.cs b/src/Security/Authentication/Twitter/ref/Microsoft.AspNetCore.Authentication.Twitter.netcoreapp.cs index 4a9a392607..24c727c352 100644 --- a/src/Security/Authentication/Twitter/ref/Microsoft.AspNetCore.Authentication.Twitter.netcoreapp.cs +++ b/src/Security/Authentication/Twitter/ref/Microsoft.AspNetCore.Authentication.Twitter.netcoreapp.cs @@ -6,16 +6,16 @@ namespace Microsoft.AspNetCore.Authentication.Twitter public partial class AccessToken : Microsoft.AspNetCore.Authentication.Twitter.RequestToken { public AccessToken() { } - public string ScreenName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string ScreenName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RequestToken { public RequestToken() { } - public bool CallbackConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Token { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string TokenSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool CallbackConfirmed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Token { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string TokenSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RequestTokenSerializer : Microsoft.AspNetCore.Authentication.IDataSerializer<Microsoft.AspNetCore.Authentication.Twitter.RequestToken> { @@ -28,11 +28,11 @@ namespace Microsoft.AspNetCore.Authentication.Twitter public partial class TwitterCreatingTicketContext : Microsoft.AspNetCore.Authentication.ResultContext<Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions> { public TwitterCreatingTicketContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions options, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties, string userId, string screenName, string accessToken, string accessTokenSecret, System.Text.Json.JsonElement user) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions)) { } - public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string AccessTokenSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ScreenName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Text.Json.JsonElement User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string AccessTokenSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ScreenName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Text.Json.JsonElement User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class TwitterDefaults { @@ -42,8 +42,8 @@ namespace Microsoft.AspNetCore.Authentication.Twitter public partial class TwitterEvents : Microsoft.AspNetCore.Authentication.RemoteAuthenticationEvents { public TwitterEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext, System.Threading.Tasks.Task> OnCreatingTicket { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions>, System.Threading.Tasks.Task> OnRedirectToAuthorizationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext, System.Threading.Tasks.Task> OnCreatingTicket { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions>, System.Threading.Tasks.Task> OnRedirectToAuthorizationEndpoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task CreatingTicket(Microsoft.AspNetCore.Authentication.Twitter.TwitterCreatingTicketContext context) { throw null; } public virtual System.Threading.Tasks.Task RedirectToAuthorizationEndpoint(Microsoft.AspNetCore.Authentication.RedirectContext<Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions> context) { throw null; } } @@ -62,13 +62,13 @@ namespace Microsoft.AspNetCore.Authentication.Twitter public partial class TwitterOptions : Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions { public TwitterOptions() { } - public Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimActionCollection ClaimActions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ConsumerKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ConsumerSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimActionCollection ClaimActions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ConsumerKey { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ConsumerSecret { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.Twitter.TwitterEvents Events { get { throw null; } set { } } - public bool RetrieveUserDetails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool RetrieveUserDetails { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Http.CookieBuilder StateCookie { get { throw null; } set { } } - public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.Twitter.RequestToken> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.Twitter.RequestToken> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Validate() { } } public partial class TwitterPostConfigureOptions : Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.AspNetCore.Authentication.Twitter.TwitterOptions> diff --git a/src/Security/Authentication/Twitter/src/TwitterHandler.cs b/src/Security/Authentication/Twitter/src/TwitterHandler.cs index e963d7a27e..5f09e608b9 100644 --- a/src/Security/Authentication/Twitter/src/TwitterHandler.cs +++ b/src/Security/Authentication/Twitter/src/TwitterHandler.cs @@ -21,8 +21,6 @@ namespace Microsoft.AspNetCore.Authentication.Twitter { public class TwitterHandler : RemoteAuthenticationHandler<TwitterOptions> { - private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - private HttpClient Backchannel => Options.Backchannel; /// <summary> @@ -301,9 +299,9 @@ namespace Microsoft.AspNetCore.Authentication.Twitter return result; } - private static string GenerateTimeStamp() + private string GenerateTimeStamp() { - var secondsSinceUnixEpocStart = DateTime.UtcNow - Epoch; + var secondsSinceUnixEpocStart = Clock.UtcNow - DateTimeOffset.UnixEpoch; return Convert.ToInt64(secondsSinceUnixEpocStart.TotalSeconds).ToString(CultureInfo.InvariantCulture); } diff --git a/src/Security/Authentication/WsFederation/ref/Microsoft.AspNetCore.Authentication.WsFederation.netcoreapp.cs b/src/Security/Authentication/WsFederation/ref/Microsoft.AspNetCore.Authentication.WsFederation.netcoreapp.cs index 3ff5d598c0..e2b391fd1e 100644 --- a/src/Security/Authentication/WsFederation/ref/Microsoft.AspNetCore.Authentication.WsFederation.netcoreapp.cs +++ b/src/Security/Authentication/WsFederation/ref/Microsoft.AspNetCore.Authentication.WsFederation.netcoreapp.cs @@ -6,36 +6,36 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation public partial class AuthenticationFailedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> { public AuthenticationFailedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions options) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Exception Exception { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class MessageReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> { public MessageReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class RedirectContext : Microsoft.AspNetCore.Authentication.PropertiesContext<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> { public RedirectContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool Handled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void HandleResponse() { } } public partial class RemoteSignOutContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> { public RemoteSignOutContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions options, Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage message) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SecurityTokenReceivedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> { public SecurityTokenReceivedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions options, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class SecurityTokenValidatedContext : Microsoft.AspNetCore.Authentication.RemoteAuthenticationContext<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> { public SecurityTokenValidatedContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Authentication.AuthenticationScheme scheme, Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions options, System.Security.Claims.ClaimsPrincipal principal, Microsoft.AspNetCore.Authentication.AuthenticationProperties properties) : base (default(Microsoft.AspNetCore.Http.HttpContext), default(Microsoft.AspNetCore.Authentication.AuthenticationScheme), default(Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions), default(Microsoft.AspNetCore.Authentication.AuthenticationProperties)) { } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Tokens.SecurityToken SecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationMessage ProtocolMessage { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Tokens.SecurityToken SecurityToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class WsFederationDefaults { @@ -46,12 +46,12 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation public partial class WsFederationEvents : Microsoft.AspNetCore.Authentication.RemoteAuthenticationEvents { public WsFederationEvents() { } - public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.MessageReceivedContext, System.Threading.Tasks.Task> OnMessageReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.RedirectContext, System.Threading.Tasks.Task> OnRedirectToIdentityProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.RemoteSignOutContext, System.Threading.Tasks.Task> OnRemoteSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.SecurityTokenReceivedContext, System.Threading.Tasks.Task> OnSecurityTokenReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.SecurityTokenValidatedContext, System.Threading.Tasks.Task> OnSecurityTokenValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.AuthenticationFailedContext, System.Threading.Tasks.Task> OnAuthenticationFailed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.MessageReceivedContext, System.Threading.Tasks.Task> OnMessageReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.RedirectContext, System.Threading.Tasks.Task> OnRedirectToIdentityProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.RemoteSignOutContext, System.Threading.Tasks.Task> OnRemoteSignOut { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.SecurityTokenReceivedContext, System.Threading.Tasks.Task> OnSecurityTokenReceived { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Authentication.WsFederation.SecurityTokenValidatedContext, System.Threading.Tasks.Task> OnSecurityTokenValidated { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Threading.Tasks.Task AuthenticationFailed(Microsoft.AspNetCore.Authentication.WsFederation.AuthenticationFailedContext context) { throw null; } public virtual System.Threading.Tasks.Task MessageReceived(Microsoft.AspNetCore.Authentication.WsFederation.MessageReceivedContext context) { throw null; } public virtual System.Threading.Tasks.Task RedirectToIdentityProvider(Microsoft.AspNetCore.Authentication.WsFederation.RedirectContext context) { throw null; } @@ -77,25 +77,25 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation public partial class WsFederationOptions : Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions { public WsFederationOptions() { } - public bool AllowUnsolicitedLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.IdentityModel.Protocols.IConfigurationManager<Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConfiguration> ConfigurationManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowUnsolicitedLogins { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.IdentityModel.Protocols.IConfigurationManager<Microsoft.IdentityModel.Protocols.WsFederation.WsFederationConfiguration> ConfigurationManager { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public new Microsoft.AspNetCore.Authentication.WsFederation.WsFederationEvents Events { get { throw null; } set { } } - public string MetadataAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RefreshOnIssuerKeyNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.PathString RemoteSignOutPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool RequireHttpsMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string MetadataAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RefreshOnIssuerKeyNotFound { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.PathString RemoteSignOutPath { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool RequireHttpsMetadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public new bool SaveTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public new bool SaveTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.ICollection<Microsoft.IdentityModel.Tokens.ISecurityTokenValidator> SecurityTokenHandlers { get { throw null; } set { } } - public string SignOutScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string SignOutWreply { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SkipUnrecognizedRequests { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string SignOutScheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string SignOutWreply { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SkipUnrecognizedRequests { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authentication.ISecureDataFormat<Microsoft.AspNetCore.Authentication.AuthenticationProperties> StateDataFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.IdentityModel.Tokens.TokenValidationParameters TokenValidationParameters { get { throw null; } set { } } - public bool UseTokenLifetime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Wreply { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Wtrealm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool UseTokenLifetime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Wreply { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Wtrealm { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Validate() { } } public partial class WsFederationPostConfigureOptions : Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions> diff --git a/src/Security/Authentication/WsFederation/src/WsFederationHandler.cs b/src/Security/Authentication/WsFederation/src/WsFederationHandler.cs index 27bb332ccf..41b9509f57 100644 --- a/src/Security/Authentication/WsFederation/src/WsFederationHandler.cs +++ b/src/Security/Authentication/WsFederation/src/WsFederationHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Authentication.WsFederation /// <summary> /// Overridden to handle remote signout requests /// </summary> - /// <returns><code>true</code> if request processing should stop.</returns> + /// <returns><see langword="true" /> if request processing should stop.</returns> public override Task<bool> HandleRequestAsync() { // RemoteSignOutPath and CallbackPath may be the same, fall through if the message doesn't match. diff --git a/src/Security/Authentication/test/SharedAuthenticationTests.cs b/src/Security/Authentication/test/SharedAuthenticationTests.cs index 36956f8374..834efeaedd 100644 --- a/src/Security/Authentication/test/SharedAuthenticationTests.cs +++ b/src/Security/Authentication/test/SharedAuthenticationTests.cs @@ -203,6 +203,46 @@ namespace Microsoft.AspNetCore.Authentication Assert.Equal(0, forwardDefault.SignOutCount); } + private class RunOnce : IClaimsTransformation + { + public int Ran = 0; + public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) + { + Ran++; + return Task.FromResult(new ClaimsPrincipal()); + } + } + + [Fact] + public async Task ForwardAuthenticateOnlyRunsTransformOnceByDefault() + { + var services = new ServiceCollection().AddLogging(); + var transform = new RunOnce(); + var builder = services.AddSingleton<IClaimsTransformation>(transform).AddAuthentication(o => + { + o.DefaultScheme = DefaultScheme; + o.AddScheme<TestHandler2>("auth1", "auth1"); + o.AddScheme<TestHandler>("specific", "specific"); + }); + RegisterAuth(builder, o => + { + o.ForwardDefault = "auth1"; + o.ForwardAuthenticate = "specific"; + }); + + var specific = new TestHandler(); + services.AddSingleton(specific); + var forwardDefault = new TestHandler2(); + services.AddSingleton(forwardDefault); + + var sp = services.BuildServiceProvider(); + var context = new DefaultHttpContext(); + context.RequestServices = sp; + + await context.AuthenticateAsync(); + Assert.Equal(1, transform.Ran); + } + [Fact] public async Task ForwardAuthenticateWinsOverDefault() { diff --git a/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netcoreapp.cs b/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netcoreapp.cs index ab30a7c6d5..b3141c4979 100644 --- a/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netcoreapp.cs +++ b/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netcoreapp.cs @@ -11,8 +11,8 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationFailure { internal AuthorizationFailure() { } - public bool FailCalled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> FailedRequirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool FailCalled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> FailedRequirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.AuthorizationFailure ExplicitFail() { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationFailure Failed(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> failed) { throw null; } } @@ -22,9 +22,9 @@ namespace Microsoft.AspNetCore.Authorization public virtual bool HasFailed { get { throw null; } } public virtual bool HasSucceeded { get { throw null; } } public virtual System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> PendingRequirements { get { throw null; } } - public virtual System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual void Fail() { } public virtual void Succeed(Microsoft.AspNetCore.Authorization.IAuthorizationRequirement requirement) { } } @@ -45,9 +45,9 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationOptions { public AuthorizationOptions() { } - public Microsoft.AspNetCore.Authorization.AuthorizationPolicy DefaultPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authorization.AuthorizationPolicy FallbackPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool InvokeHandlersAfterFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authorization.AuthorizationPolicy DefaultPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authorization.AuthorizationPolicy FallbackPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool InvokeHandlersAfterFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void AddPolicy(string name, Microsoft.AspNetCore.Authorization.AuthorizationPolicy policy) { } public void AddPolicy(string name, System.Action<Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder> configurePolicy) { } public Microsoft.AspNetCore.Authorization.AuthorizationPolicy GetPolicy(string name) { throw null; } @@ -55,8 +55,8 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationPolicy { public AuthorizationPolicy(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> requirements, System.Collections.Generic.IEnumerable<string> authenticationSchemes) { } - public System.Collections.Generic.IReadOnlyList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.AuthorizationPolicy Combine(params Microsoft.AspNetCore.Authorization.AuthorizationPolicy[] policies) { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationPolicy Combine(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.AuthorizationPolicy> policies) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -66,8 +66,8 @@ namespace Microsoft.AspNetCore.Authorization { public AuthorizationPolicyBuilder(Microsoft.AspNetCore.Authorization.AuthorizationPolicy policy) { } public AuthorizationPolicyBuilder(params string[] authenticationSchemes) { } - public System.Collections.Generic.IList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder AddAuthenticationSchemes(params string[] schemes) { throw null; } public Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder AddRequirements(params Microsoft.AspNetCore.Authorization.IAuthorizationRequirement[] requirements) { throw null; } public Microsoft.AspNetCore.Authorization.AuthorizationPolicy Build() { throw null; } @@ -85,8 +85,8 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationResult { internal AuthorizationResult() { } - public Microsoft.AspNetCore.Authorization.AuthorizationFailure Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authorization.AuthorizationFailure Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.AuthorizationResult Failed() { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationResult Failed(Microsoft.AspNetCore.Authorization.AuthorizationFailure failure) { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationResult Success() { throw null; } @@ -103,9 +103,9 @@ namespace Microsoft.AspNetCore.Authorization { public AuthorizeAttribute() { } public AuthorizeAttribute(string policy) { } - public string AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DefaultAuthorizationEvaluator : Microsoft.AspNetCore.Authorization.IAuthorizationEvaluator { @@ -174,32 +174,37 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure { public AssertionRequirement(System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, bool> handler) { } public AssertionRequirement(System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, System.Threading.Tasks.Task<bool>> handler) { } - public System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, System.Threading.Tasks.Task<bool>> Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, System.Threading.Tasks.Task<bool>> Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task HandleAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context) { throw null; } + public override string ToString() { throw null; } } public partial class ClaimsAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.ClaimsAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public ClaimsAuthorizationRequirement(string claimType, System.Collections.Generic.IEnumerable<string> allowedValues) { } - public System.Collections.Generic.IEnumerable<string> AllowedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable<string> AllowedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.ClaimsAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } public partial class DenyAnonymousAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.DenyAnonymousAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public DenyAnonymousAuthorizationRequirement() { } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.DenyAnonymousAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } public partial class NameAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.NameAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public NameAuthorizationRequirement(string requiredName) { } - public string RequiredName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string RequiredName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.NameAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } public partial class OperationAuthorizationRequirement : Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public OperationAuthorizationRequirement() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override string ToString() { throw null; } } public partial class PassThroughAuthorizationHandler : Microsoft.AspNetCore.Authorization.IAuthorizationHandler { @@ -210,8 +215,9 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure public partial class RolesAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public RolesAuthorizationRequirement(System.Collections.Generic.IEnumerable<string> allowedRoles) { } - public System.Collections.Generic.IEnumerable<string> AllowedRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable<string> AllowedRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netstandard2.0.cs b/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netstandard2.0.cs index ab30a7c6d5..b3141c4979 100644 --- a/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netstandard2.0.cs +++ b/src/Security/Authorization/Core/ref/Microsoft.AspNetCore.Authorization.netstandard2.0.cs @@ -11,8 +11,8 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationFailure { internal AuthorizationFailure() { } - public bool FailCalled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> FailedRequirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool FailCalled { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> FailedRequirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.AuthorizationFailure ExplicitFail() { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationFailure Failed(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> failed) { throw null; } } @@ -22,9 +22,9 @@ namespace Microsoft.AspNetCore.Authorization public virtual bool HasFailed { get { throw null; } } public virtual bool HasSucceeded { get { throw null; } } public virtual System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> PendingRequirements { get { throw null; } } - public virtual System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public virtual System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual object Resource { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public virtual System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual void Fail() { } public virtual void Succeed(Microsoft.AspNetCore.Authorization.IAuthorizationRequirement requirement) { } } @@ -45,9 +45,9 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationOptions { public AuthorizationOptions() { } - public Microsoft.AspNetCore.Authorization.AuthorizationPolicy DefaultPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Authorization.AuthorizationPolicy FallbackPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool InvokeHandlersAfterFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Authorization.AuthorizationPolicy DefaultPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Authorization.AuthorizationPolicy FallbackPolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool InvokeHandlersAfterFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void AddPolicy(string name, Microsoft.AspNetCore.Authorization.AuthorizationPolicy policy) { } public void AddPolicy(string name, System.Action<Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder> configurePolicy) { } public Microsoft.AspNetCore.Authorization.AuthorizationPolicy GetPolicy(string name) { throw null; } @@ -55,8 +55,8 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationPolicy { public AuthorizationPolicy(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> requirements, System.Collections.Generic.IEnumerable<string> authenticationSchemes) { } - public System.Collections.Generic.IReadOnlyList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IReadOnlyList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.AuthorizationPolicy Combine(params Microsoft.AspNetCore.Authorization.AuthorizationPolicy[] policies) { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationPolicy Combine(System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Authorization.AuthorizationPolicy> policies) { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -66,8 +66,8 @@ namespace Microsoft.AspNetCore.Authorization { public AuthorizationPolicyBuilder(Microsoft.AspNetCore.Authorization.AuthorizationPolicy policy) { } public AuthorizationPolicyBuilder(params string[] authenticationSchemes) { } - public System.Collections.Generic.IList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList<string> AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<Microsoft.AspNetCore.Authorization.IAuthorizationRequirement> Requirements { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder AddAuthenticationSchemes(params string[] schemes) { throw null; } public Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder AddRequirements(params Microsoft.AspNetCore.Authorization.IAuthorizationRequirement[] requirements) { throw null; } public Microsoft.AspNetCore.Authorization.AuthorizationPolicy Build() { throw null; } @@ -85,8 +85,8 @@ namespace Microsoft.AspNetCore.Authorization public partial class AuthorizationResult { internal AuthorizationResult() { } - public Microsoft.AspNetCore.Authorization.AuthorizationFailure Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Authorization.AuthorizationFailure Failure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.AuthorizationResult Failed() { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationResult Failed(Microsoft.AspNetCore.Authorization.AuthorizationFailure failure) { throw null; } public static Microsoft.AspNetCore.Authorization.AuthorizationResult Success() { throw null; } @@ -103,9 +103,9 @@ namespace Microsoft.AspNetCore.Authorization { public AuthorizeAttribute() { } public AuthorizeAttribute(string policy) { } - public string AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticationSchemes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Policy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Roles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class DefaultAuthorizationEvaluator : Microsoft.AspNetCore.Authorization.IAuthorizationEvaluator { @@ -174,32 +174,37 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure { public AssertionRequirement(System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, bool> handler) { } public AssertionRequirement(System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, System.Threading.Tasks.Task<bool>> handler) { } - public System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, System.Threading.Tasks.Task<bool>> Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Func<Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext, System.Threading.Tasks.Task<bool>> Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task HandleAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context) { throw null; } + public override string ToString() { throw null; } } public partial class ClaimsAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.ClaimsAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public ClaimsAuthorizationRequirement(string claimType, System.Collections.Generic.IEnumerable<string> allowedValues) { } - public System.Collections.Generic.IEnumerable<string> AllowedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable<string> AllowedValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string ClaimType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.ClaimsAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } public partial class DenyAnonymousAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.DenyAnonymousAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public DenyAnonymousAuthorizationRequirement() { } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.DenyAnonymousAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } public partial class NameAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.NameAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public NameAuthorizationRequirement(string requiredName) { } - public string RequiredName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string RequiredName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.NameAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } public partial class OperationAuthorizationRequirement : Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public OperationAuthorizationRequirement() { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override string ToString() { throw null; } } public partial class PassThroughAuthorizationHandler : Microsoft.AspNetCore.Authorization.IAuthorizationHandler { @@ -210,8 +215,9 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure public partial class RolesAuthorizationRequirement : Microsoft.AspNetCore.Authorization.AuthorizationHandler<Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement>, Microsoft.AspNetCore.Authorization.IAuthorizationRequirement { public RolesAuthorizationRequirement(System.Collections.Generic.IEnumerable<string> allowedRoles) { } - public System.Collections.Generic.IEnumerable<string> AllowedRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IEnumerable<string> AllowedRoles { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } protected override System.Threading.Tasks.Task HandleRequirementAsync(Microsoft.AspNetCore.Authorization.AuthorizationHandlerContext context, Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement requirement) { throw null; } + public override string ToString() { throw null; } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/Security/Authorization/Core/src/AssertionRequirement.cs b/src/Security/Authorization/Core/src/AssertionRequirement.cs index 5fa452b733..0c31f57105 100644 --- a/src/Security/Authorization/Core/src/AssertionRequirement.cs +++ b/src/Security/Authorization/Core/src/AssertionRequirement.cs @@ -56,5 +56,10 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure context.Succeed(this); } } + + public override string ToString() + { + return $"{nameof(Handler)} assertion should evaluate to true."; + } } } diff --git a/src/Security/Authorization/Core/src/AuthorizationPolicy.cs b/src/Security/Authorization/Core/src/AuthorizationPolicy.cs index f1833da954..b7c52722fa 100644 --- a/src/Security/Authorization/Core/src/AuthorizationPolicy.cs +++ b/src/Security/Authorization/Core/src/AuthorizationPolicy.cs @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Authorization throw new ArgumentNullException(nameof(authenticationSchemes)); } - if (requirements.Count() == 0) + if (!requirements.Any()) { throw new InvalidOperationException(Resources.Exception_AuthorizationPolicyEmpty); } @@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Authorization } var rolesSplit = authorizeDatum.Roles?.Split(','); - if (rolesSplit != null && rolesSplit.Any()) + if (rolesSplit?.Length > 0) { var trimmedRolesSplit = rolesSplit.Where(r => !string.IsNullOrWhiteSpace(r)).Select(r => r.Trim()); policyBuilder.RequireRole(trimmedRolesSplit); @@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.Authorization } var authTypesSplit = authorizeDatum.AuthenticationSchemes?.Split(','); - if (authTypesSplit != null && authTypesSplit.Any()) + if (authTypesSplit?.Length > 0) { foreach (var authType in authTypesSplit) { diff --git a/src/Security/Authorization/Core/src/AuthorizationPolicyBuilder.cs b/src/Security/Authorization/Core/src/AuthorizationPolicyBuilder.cs index 2f483e37ce..ffcc339aae 100644 --- a/src/Security/Authorization/Core/src/AuthorizationPolicyBuilder.cs +++ b/src/Security/Authorization/Core/src/AuthorizationPolicyBuilder.cs @@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Authorization /// Adds a <see cref="ClaimsAuthorizationRequirement"/> /// to the current instance. /// </summary> - /// <param name="claimType">The claim type required, which no restrictions on claim value.</param> + /// <param name="claimType">The claim type required, with no restrictions on claim value.</param> /// <returns>A reference to this instance after the operation has completed.</returns> public AuthorizationPolicyBuilder RequireClaim(string claimType) { diff --git a/src/Security/Authorization/Core/src/ClaimsAuthorizationRequirement.cs b/src/Security/Authorization/Core/src/ClaimsAuthorizationRequirement.cs index 93b1deea6d..f77b74fd74 100644 --- a/src/Security/Authorization/Core/src/ClaimsAuthorizationRequirement.cs +++ b/src/Security/Authorization/Core/src/ClaimsAuthorizationRequirement.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; namespace Microsoft.AspNetCore.Authorization.Infrastructure @@ -69,5 +70,14 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure } return Task.CompletedTask; } + + public override string ToString() + { + var value = (AllowedValues == null || !AllowedValues.Any()) + ? string.Empty + : $" and Claim.Value is one of the following values: ({string.Join("|", AllowedValues)})"; + + return $"{nameof(ClaimsAuthorizationRequirement)}:Claim.Type={ClaimType}{value}"; + } } } diff --git a/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs b/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs index bc5d571c47..475dea3330 100644 --- a/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs +++ b/src/Security/Authorization/Core/src/DefaultAuthorizationService.cs @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Authorization } else { - _logger.UserAuthorizationFailed(); + _logger.UserAuthorizationFailed(result.Failure); } return result; } @@ -132,4 +132,4 @@ namespace Microsoft.AspNetCore.Authorization return await this.AuthorizeAsync(user, resource, policy); } } -} \ No newline at end of file +} diff --git a/src/Security/Authorization/Core/src/DenyAnonymousAuthorizationRequirement.cs b/src/Security/Authorization/Core/src/DenyAnonymousAuthorizationRequirement.cs index e88cce7aac..35828735a5 100644 --- a/src/Security/Authorization/Core/src/DenyAnonymousAuthorizationRequirement.cs +++ b/src/Security/Authorization/Core/src/DenyAnonymousAuthorizationRequirement.cs @@ -29,5 +29,10 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure } return Task.CompletedTask; } + + public override string ToString() + { + return $"{nameof(DenyAnonymousAuthorizationRequirement)}:Requires an authenticated user."; + } } } diff --git a/src/Security/Authorization/Core/src/LoggingExtensions.cs b/src/Security/Authorization/Core/src/LoggingExtensions.cs index e31d88161d..ef57f8c09f 100644 --- a/src/Security/Authorization/Core/src/LoggingExtensions.cs +++ b/src/Security/Authorization/Core/src/LoggingExtensions.cs @@ -2,12 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Authorization; namespace Microsoft.Extensions.Logging { internal static class LoggingExtensions { - private static Action<ILogger, Exception> _userAuthorizationFailed; + private static Action<ILogger, string, Exception> _userAuthorizationFailed; private static Action<ILogger, Exception> _userAuthorizationSucceeded; static LoggingExtensions() @@ -16,16 +17,22 @@ namespace Microsoft.Extensions.Logging eventId: new EventId(1, "UserAuthorizationSucceeded"), logLevel: LogLevel.Information, formatString: "Authorization was successful."); - _userAuthorizationFailed = LoggerMessage.Define( + _userAuthorizationFailed = LoggerMessage.Define<string>( eventId: new EventId(2, "UserAuthorizationFailed"), logLevel: LogLevel.Information, - formatString: "Authorization failed."); + formatString: "Authorization failed for {0}"); } public static void UserAuthorizationSucceeded(this ILogger logger) => _userAuthorizationSucceeded(logger, null); - public static void UserAuthorizationFailed(this ILogger logger) - => _userAuthorizationFailed(logger, null); + public static void UserAuthorizationFailed(this ILogger logger, AuthorizationFailure failure) + { + var reason = failure.FailCalled + ? "Fail() was explicitly called." + : "These requirements were not met:" + Environment.NewLine + string.Join(Environment.NewLine, failure.FailedRequirements); + + _userAuthorizationFailed(logger, reason, null); + } } } diff --git a/src/Security/Authorization/Core/src/NameAuthorizationRequirement.cs b/src/Security/Authorization/Core/src/NameAuthorizationRequirement.cs index 02ab946fad..36cee10aac 100644 --- a/src/Security/Authorization/Core/src/NameAuthorizationRequirement.cs +++ b/src/Security/Authorization/Core/src/NameAuthorizationRequirement.cs @@ -48,5 +48,10 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure } return Task.CompletedTask; } + + public override string ToString() + { + return $"{nameof(NameAuthorizationRequirement)}:Requires a user identity with Name equal to {RequiredName}"; + } } } diff --git a/src/Security/Authorization/Core/src/OperationAuthorizationRequirement.cs b/src/Security/Authorization/Core/src/OperationAuthorizationRequirement.cs index c3f16356d3..0e2a6fcf3f 100644 --- a/src/Security/Authorization/Core/src/OperationAuthorizationRequirement.cs +++ b/src/Security/Authorization/Core/src/OperationAuthorizationRequirement.cs @@ -13,5 +13,10 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure /// The name of this instance of <see cref="IAuthorizationRequirement"/>. /// </summary> public string Name { get; set; } + + public override string ToString() + { + return $"{nameof(OperationAuthorizationRequirement)}:Name={Name}"; + } } } diff --git a/src/Security/Authorization/Core/src/RolesAuthorizationRequirement.cs b/src/Security/Authorization/Core/src/RolesAuthorizationRequirement.cs index 811e17aacd..e5a2251a14 100644 --- a/src/Security/Authorization/Core/src/RolesAuthorizationRequirement.cs +++ b/src/Security/Authorization/Core/src/RolesAuthorizationRequirement.cs @@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure throw new ArgumentNullException(nameof(allowedRoles)); } - if (allowedRoles.Count() == 0) + if (!allowedRoles.Any()) { throw new InvalidOperationException(Resources.Exception_RoleRequirementEmpty); } @@ -64,5 +64,11 @@ namespace Microsoft.AspNetCore.Authorization.Infrastructure return Task.CompletedTask; } + public override string ToString() + { + var roles = $"User.IsInRole must be true for one of the following roles: ({string.Join("|", AllowedRoles)})"; + + return $"{nameof(RolesAuthorizationRequirement)}:{roles}"; + } } } diff --git a/src/Security/Authorization/Policy/ref/Microsoft.AspNetCore.Authorization.Policy.netcoreapp.cs b/src/Security/Authorization/Policy/ref/Microsoft.AspNetCore.Authorization.Policy.netcoreapp.cs index 571d21a03d..138cd20ea5 100644 --- a/src/Security/Authorization/Policy/ref/Microsoft.AspNetCore.Authorization.Policy.netcoreapp.cs +++ b/src/Security/Authorization/Policy/ref/Microsoft.AspNetCore.Authorization.Policy.netcoreapp.cs @@ -20,9 +20,9 @@ namespace Microsoft.AspNetCore.Authorization.Policy public partial class PolicyAuthorizationResult { internal PolicyAuthorizationResult() { } - public bool Challenged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool Forbidden { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool Challenged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool Forbidden { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool Succeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Authorization.Policy.PolicyAuthorizationResult Challenge() { throw null; } public static Microsoft.AspNetCore.Authorization.Policy.PolicyAuthorizationResult Forbid() { throw null; } public static Microsoft.AspNetCore.Authorization.Policy.PolicyAuthorizationResult Success() { throw null; } diff --git a/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs b/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs index 686374d829..af115e9daa 100644 --- a/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs +++ b/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Authorization if (authorizeResult.Challenged) { - if (policy.AuthenticationSchemes.Any()) + if (policy.AuthenticationSchemes.Count > 0) { foreach (var scheme in policy.AuthenticationSchemes) { @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Authorization } else if (authorizeResult.Forbidden) { - if (policy.AuthenticationSchemes.Any()) + if (policy.AuthenticationSchemes.Count > 0) { foreach (var scheme in policy.AuthenticationSchemes) { diff --git a/src/Security/Authorization/test/AssertionRequirementsTests.cs b/src/Security/Authorization/test/AssertionRequirementsTests.cs new file mode 100644 index 0000000000..d197860329 --- /dev/null +++ b/src/Security/Authorization/test/AssertionRequirementsTests.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization.Test +{ + public class AssertionRequirementsTests + { + private AssertionRequirement CreateRequirement() + { + return new AssertionRequirement(context => true); + } + + [Fact] + public void ToString_ShouldReturnFormatValue() + { + // Arrange + var requirement = new AssertionRequirement(context => true); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("Handler assertion should evaluate to true.", formattedValue); + } + } +} diff --git a/src/Security/Authorization/test/AuthorizationMiddlewareTests.cs b/src/Security/Authorization/test/AuthorizationMiddlewareTests.cs index 86858f4fe1..075a6ee655 100644 --- a/src/Security/Authorization/test/AuthorizationMiddlewareTests.cs +++ b/src/Security/Authorization/test/AuthorizationMiddlewareTests.cs @@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Authorization.Test // Assert Assert.False(next.Called); } - + [Fact] public async Task HasEndpointWithoutAuth_AnonymousUser_Allows() { @@ -135,6 +135,27 @@ namespace Microsoft.AspNetCore.Authorization.Test Assert.True(authenticationService.ChallengeCalled); } + [Fact] + public async Task HasEndpointWithAuth_ChallengesAuthenticationSchemes() + { + // Arrange + var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); + var policyProvider = new Mock<IAuthorizationPolicyProvider>(); + policyProvider.Setup(p => p.GetDefaultPolicyAsync()).ReturnsAsync(policy); + var next = new TestRequestDelegate(); + var authenticationService = new TestAuthenticationService(); + + var middleware = CreateMiddleware(next.Invoke, policyProvider.Object); + var context = GetHttpContext(endpoint: CreateEndpoint(new AuthorizeAttribute() { AuthenticationSchemes = "whatever"}), authenticationService: authenticationService); + + // Act + await middleware.Invoke(context); + + // Assert + Assert.False(next.Called); + Assert.True(authenticationService.ChallengeCalled); + } + [Fact] public async Task HasEndpointWithAuth_AnonymousUser_ChallengePerScheme() { diff --git a/src/Security/Authorization/test/ClaimsAuthorizationRequirementTests.cs b/src/Security/Authorization/test/ClaimsAuthorizationRequirementTests.cs new file mode 100644 index 0000000000..d1bbe69a64 --- /dev/null +++ b/src/Security/Authorization/test/ClaimsAuthorizationRequirementTests.cs @@ -0,0 +1,58 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization.Test +{ + public class ClaimsAuthorizationRequirementTests + { + public ClaimsAuthorizationRequirement CreateRequirement(string claimType, params string[] allowedValues) + { + return new ClaimsAuthorizationRequirement(claimType, allowedValues); + } + + [Fact] + public void ToString_ShouldReturnAndDescriptionWhenAllowedValuesNotNull() + { + // Arrange + var requirement = CreateRequirement("Custom", "CustomValue1", "CustomValue2"); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("ClaimsAuthorizationRequirement:Claim.Type=Custom and Claim.Value is one of the following values: (CustomValue1|CustomValue2)", formattedValue); + } + + [Fact] + public void ToString_ShouldReturnWithoutAllowedDescriptionWhenAllowedValuesIsNull() + { + // Arrange + var requirement = CreateRequirement("Custom", (string[])null); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("ClaimsAuthorizationRequirement:Claim.Type=Custom", formattedValue); + } + + [Fact] + public void ToString_ShouldReturnWithoutAllowedDescriptionWhenAllowedValuesIsEmpty() + { + // Arrange + var requirement = CreateRequirement("Custom", Array.Empty<string>()); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("ClaimsAuthorizationRequirement:Claim.Type=Custom", formattedValue); + } + } +} diff --git a/src/Security/Authorization/test/DefaultAuthorizationServiceTests.cs b/src/Security/Authorization/test/DefaultAuthorizationServiceTests.cs index d0fe9a62e9..ecd55a4acc 100644 --- a/src/Security/Authorization/test/DefaultAuthorizationServiceTests.cs +++ b/src/Security/Authorization/test/DefaultAuthorizationServiceTests.cs @@ -8,6 +8,7 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization.Infrastructure; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Xunit; @@ -64,7 +65,8 @@ namespace Microsoft.AspNetCore.Authorization.Test { services.AddAuthorization(options => { - options.AddPolicy("Basic", policy => { + options.AddPolicy("Basic", policy => + { policy.AddAuthenticationSchemes("Basic"); policy.RequireClaim("Permission", "CanViewPage"); }); @@ -710,7 +712,8 @@ namespace Microsoft.AspNetCore.Authorization.Test protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PassThroughRequirement requirement) { - if (Succeed) { + if (Succeed) + { context.Succeed(requirement); } return Task.FromResult(0); @@ -926,7 +929,6 @@ namespace Microsoft.AspNetCore.Authorization.Test Assert.True((await authorizationService.AuthorizeAsync(user, 2, Operations.Edit)).Succeeded); } - [Fact] public async Task DoesNotCallHandlerWithWrongResourceType() { @@ -1174,5 +1176,104 @@ namespace Microsoft.AspNetCore.Authorization.Test Assert.False((await authorizationService.AuthorizeAsync(null, "Success")).Succeeded); } + public class LogRequirement : IAuthorizationRequirement + { + public override string ToString() + { + return "LogRequirement"; + } + } + + public class DefaultAuthorizationServiceTestLogger : ILogger<DefaultAuthorizationService> + { + private Action<LogLevel, EventId, object, Exception, Func<object, Exception, string>> _assertion; + + public DefaultAuthorizationServiceTestLogger(Action<LogLevel, EventId, object, Exception, Func<object, Exception, string>> assertion) + { + _assertion = assertion; + } + + public IDisposable BeginScope<TState>(TState state) + { + throw new NotImplementedException(); + } + + public bool IsEnabled(LogLevel logLevel) + { + return true; + } + + public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) + { + _assertion(logLevel, eventId, state, exception, (s, e) => formatter?.Invoke((TState)s, e)); + } + } + + [Fact] + public async Task Authorize_ShouldLogRequirementDetailWhenUnHandled() + { + // Arrange + + static void Assertion(LogLevel level, EventId eventId, object state, Exception exception, Func<object, Exception, string> formatter) + { + Assert.Equal(LogLevel.Information, level); + Assert.Equal(2, eventId.Id); + Assert.Equal("UserAuthorizationFailed", eventId.Name); + var message = formatter(state, exception); + + Assert.Equal("Authorization failed for These requirements were not met:" + Environment.NewLine + "LogRequirement" + Environment.NewLine + "LogRequirement", message); + } + + var authorizationService = BuildAuthorizationService(services => + { + services.AddSingleton<ILogger<DefaultAuthorizationService>>(new DefaultAuthorizationServiceTestLogger(Assertion)); + services.AddAuthorization(options => options.AddPolicy("Log", p => + { + p.Requirements.Add(new LogRequirement()); + p.Requirements.Add(new LogRequirement()); + })); + }); + + var user = new ClaimsPrincipal(); + + // Act + var result = await authorizationService.AuthorizeAsync(user, "Log"); + + // Assert + } + + [Fact] + public async Task Authorize_ShouldLogExplicitFailedWhenFailedCall() + { + // Arrange + + static void Assertion(LogLevel level, EventId eventId, object state, Exception exception, Func<object, Exception, string> formatter) + { + Assert.Equal(LogLevel.Information, level); + Assert.Equal(2, eventId.Id); + Assert.Equal("UserAuthorizationFailed", eventId.Name); + var message = formatter(state, exception); + + Assert.Equal("Authorization failed for Fail() was explicitly called.", message); + } + + var authorizationService = BuildAuthorizationService(services => + { + services.AddSingleton<IAuthorizationHandler, FailHandler>(); + services.AddSingleton<ILogger<DefaultAuthorizationService>>(new DefaultAuthorizationServiceTestLogger(Assertion)); + services.AddAuthorization(options => options.AddPolicy("Log", p => + { + p.Requirements.Add(new LogRequirement()); + p.Requirements.Add(new LogRequirement()); + })); + }); + + var user = new ClaimsPrincipal(); + + // Act + var result = await authorizationService.AuthorizeAsync(user, "Log"); + + // Assert + } } } diff --git a/src/Security/Authorization/test/DenyAnonymousAuthorizationRequirementTests.cs b/src/Security/Authorization/test/DenyAnonymousAuthorizationRequirementTests.cs new file mode 100644 index 0000000000..3d35634758 --- /dev/null +++ b/src/Security/Authorization/test/DenyAnonymousAuthorizationRequirementTests.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization.Test +{ + public class DenyAnonymousAuthorizationRequirementTests + { + private DenyAnonymousAuthorizationRequirement CreateRequirement() + { + return new DenyAnonymousAuthorizationRequirement(); + } + + [Fact] + public void ToString_ShouldReturnFormatValue() + { + // Arrange + var requirement = CreateRequirement(); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("DenyAnonymousAuthorizationRequirement:Requires an authenticated user.", formattedValue); + } + } +} diff --git a/src/Security/Authorization/test/NameAuthorizationRequirementTests.cs b/src/Security/Authorization/test/NameAuthorizationRequirementTests.cs new file mode 100644 index 0000000000..73a9a98144 --- /dev/null +++ b/src/Security/Authorization/test/NameAuthorizationRequirementTests.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization.Test +{ + public class NameAuthorizationRequirementTests + { + public NameAuthorizationRequirement CreateRequirement(string requiredName) + { + return new NameAuthorizationRequirement(requiredName); + } + + [Fact] + public void ToString_ShouldReturnFormatValue() + { + // Arrange + var requirement = CreateRequirement("Custom"); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("NameAuthorizationRequirement:Requires a user identity with Name equal to Custom", formattedValue); + } + } +} diff --git a/src/Security/Authorization/test/OperationAuthorizationRequirementTests.cs b/src/Security/Authorization/test/OperationAuthorizationRequirementTests.cs new file mode 100644 index 0000000000..623d01c98e --- /dev/null +++ b/src/Security/Authorization/test/OperationAuthorizationRequirementTests.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization.Test +{ + public class OperationAuthorizationRequirementTests + { + private OperationAuthorizationRequirement CreateRequirement(string name) + { + return new OperationAuthorizationRequirement() + { + Name = name + }; + } + + [Fact] + public void ToString_ShouldReturnFormatValue() + { + // Arrange + var requirement = CreateRequirement("Custom"); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("OperationAuthorizationRequirement:Name=Custom", formattedValue); + } + } +} diff --git a/src/Security/Authorization/test/RolesAuthorizationRequirementTests.cs b/src/Security/Authorization/test/RolesAuthorizationRequirementTests.cs new file mode 100644 index 0000000000..1b8d5b09c7 --- /dev/null +++ b/src/Security/Authorization/test/RolesAuthorizationRequirementTests.cs @@ -0,0 +1,45 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Authorization.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization.Test +{ + public class RolesAuthorizationRequirementTests + { + private RolesAuthorizationRequirement CreateRequirement(params string[] allowedRoles) + { + return new RolesAuthorizationRequirement(allowedRoles); + } + + [Fact] + public void ToString_ShouldReturnSplitByBarWhenHasTwoAllowedRoles() + { + // Arrange + var requirement = CreateRequirement("Custom1", "Custom2"); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (Custom1|Custom2)", formattedValue); + } + + [Fact] + public void ToString_ShouldReturnUnSplitStringWhenOnlyOneAllowedRoles() + { + // Arrange + var requirement = CreateRequirement("Custom1"); + + // Act + var formattedValue = requirement.ToString(); + + // Assert + Assert.Equal("RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (Custom1)",formattedValue); + } + } +} diff --git a/src/Security/CookiePolicy/ref/Microsoft.AspNetCore.CookiePolicy.netcoreapp.cs b/src/Security/CookiePolicy/ref/Microsoft.AspNetCore.CookiePolicy.netcoreapp.cs index f2e231debc..bd378bd871 100644 --- a/src/Security/CookiePolicy/ref/Microsoft.AspNetCore.CookiePolicy.netcoreapp.cs +++ b/src/Security/CookiePolicy/ref/Microsoft.AspNetCore.CookiePolicy.netcoreapp.cs @@ -11,13 +11,13 @@ namespace Microsoft.AspNetCore.Builder public partial class CookiePolicyOptions { public CookiePolicyOptions() { } - public System.Func<Microsoft.AspNetCore.Http.HttpContext, bool> CheckConsentNeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.CookieBuilder ConsentCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.SameSiteMode MinimumSameSitePolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action<Microsoft.AspNetCore.CookiePolicy.AppendCookieContext> OnAppendCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action<Microsoft.AspNetCore.CookiePolicy.DeleteCookieContext> OnDeleteCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.CookieSecurePolicy Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<Microsoft.AspNetCore.Http.HttpContext, bool> CheckConsentNeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.CookieBuilder ConsentCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.SameSiteMode MinimumSameSitePolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action<Microsoft.AspNetCore.CookiePolicy.AppendCookieContext> OnAppendCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action<Microsoft.AspNetCore.CookiePolicy.DeleteCookieContext> OnDeleteCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.CookieSecurePolicy Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.CookiePolicy @@ -25,30 +25,30 @@ namespace Microsoft.AspNetCore.CookiePolicy public partial class AppendCookieContext { public AppendCookieContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.CookieOptions options, string name, string value) { } - public Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string CookieName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string CookieValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool HasConsent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsConsentNeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IssueCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string CookieName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string CookieValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool HasConsent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsConsentNeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IssueCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class CookiePolicyMiddleware { public CookiePolicyMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Builder.CookiePolicyOptions> options) { } public CookiePolicyMiddleware(Microsoft.AspNetCore.Http.RequestDelegate next, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Builder.CookiePolicyOptions> options, Microsoft.Extensions.Logging.ILoggerFactory factory) { } - public Microsoft.AspNetCore.Builder.CookiePolicyOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Builder.CookiePolicyOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Threading.Tasks.Task Invoke(Microsoft.AspNetCore.Http.HttpContext context) { throw null; } } public partial class DeleteCookieContext { public DeleteCookieContext(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.CookieOptions options, string name) { } - public Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string CookieName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool HasConsent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsConsentNeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IssueCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.HttpContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string CookieName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.CookieOptions CookieOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool HasConsent { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsConsentNeeded { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IssueCookie { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public enum HttpOnlyPolicy { diff --git a/src/Security/CookiePolicy/src/CookiePolicyOptions.cs b/src/Security/CookiePolicy/src/CookiePolicyOptions.cs index 098bd33483..56e5998808 100644 --- a/src/Security/CookiePolicy/src/CookiePolicyOptions.cs +++ b/src/Security/CookiePolicy/src/CookiePolicyOptions.cs @@ -12,22 +12,10 @@ namespace Microsoft.AspNetCore.Builder /// </summary> public class CookiePolicyOptions { - // True (old): https://tools.ietf.org/html/draft-west-first-party-cookies-07#section-3.1 - // False (new): https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.1 - internal static bool SuppressSameSiteNone; - - static CookiePolicyOptions() - { - if (AppContext.TryGetSwitch("Microsoft.AspNetCore.SuppressSameSiteNone", out var enabled)) - { - SuppressSameSiteNone = enabled; - } - } - /// <summary> /// Affects the cookie's same site attribute. /// </summary> - public SameSiteMode MinimumSameSitePolicy { get; set; } = SuppressSameSiteNone ? SameSiteMode.None : SameSiteMode.Unspecified; + public SameSiteMode MinimumSameSitePolicy { get; set; } = SameSiteMode.Unspecified; /// <summary> /// Affects whether cookies must be HttpOnly. diff --git a/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs b/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs index 2d03c65c3d..2c1b46264e 100644 --- a/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs +++ b/src/Security/CookiePolicy/src/ResponseCookiesWrapper.cs @@ -115,8 +115,7 @@ namespace Microsoft.AspNetCore.CookiePolicy private bool CheckPolicyRequired() { return !CanTrack - || (CookiePolicyOptions.SuppressSameSiteNone && Options.MinimumSameSitePolicy != SameSiteMode.None) - || (!CookiePolicyOptions.SuppressSameSiteNone && Options.MinimumSameSitePolicy != SameSiteMode.Unspecified) + || Options.MinimumSameSitePolicy != SameSiteMode.Unspecified || Options.HttpOnly != HttpOnlyPolicy.None || Options.Secure != CookieSecurePolicy.None; } diff --git a/src/Security/README.md b/src/Security/README.md index 0ba28c1e97..5ed702c4f2 100644 --- a/src/Security/README.md +++ b/src/Security/README.md @@ -3,9 +3,9 @@ ASP.NET Core Security Contains the security and authorization middlewares for ASP.NET Core. -A list of community projects related to authentication and security for ASP.NET Core are listed in the [documentation](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/community). +A list of community projects related to authentication and security for ASP.NET Core are listed in the [documentation](https://docs.microsoft.com/aspnet/core/security/authentication/community). -See the [ASP.NET Core security documentation](https://docs.microsoft.com/en-us/aspnet/core/security/). +See the [ASP.NET Core security documentation](https://docs.microsoft.com/aspnet/core/security/). ### Notes diff --git a/src/Security/Security.sln b/src/Security/Security.sln index 93250dc8a4..32566c7143 100644 --- a/src/Security/Security.sln +++ b/src/Security/Security.sln @@ -164,8 +164,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.HttpSys", "..\Servers\HttpSys\src\Microsoft.AspNetCore.Server.HttpSys.csproj", "{D6C3C4A9-197B-47B5-8B72-35047CBC4F22}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Net.Http.Headers", "..\Http\Headers\src\Microsoft.Net.Http.Headers.csproj", "{4BB8D7D7-E111-4A86-B6E5-C1201E0DA8CE}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/Security/samples/Identity.ExternalClaims/Pages/Account/Manage/EnableAuthenticator.cshtml.cs b/src/Security/samples/Identity.ExternalClaims/Pages/Account/Manage/EnableAuthenticator.cshtml.cs index 8d0e937b34..a29b2bbc92 100644 --- a/src/Security/samples/Identity.ExternalClaims/Pages/Account/Manage/EnableAuthenticator.cshtml.cs +++ b/src/Security/samples/Identity.ExternalClaims/Pages/Account/Manage/EnableAuthenticator.cshtml.cs @@ -80,7 +80,7 @@ namespace Identity.ExternalClaims.Pages.Account.Manage return Page(); } - // Strip spaces and hypens + // Strip spaces and hyphens var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); var is2faTokenValid = await _userManager.VerifyTwoFactorTokenAsync( diff --git a/src/Security/samples/Identity.ExternalClaims/README.md b/src/Security/samples/Identity.ExternalClaims/README.md index 7a9141075d..70205c0367 100644 --- a/src/Security/samples/Identity.ExternalClaims/README.md +++ b/src/Security/samples/Identity.ExternalClaims/README.md @@ -4,7 +4,7 @@ AuthSamples.Identity.ExternalClaims Sample demonstrating copying over static and dynamic external claims from Google authentication during login: Steps: -1. Configure a google OAuth2 project. See https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins?tabs=aspnetcore2x for basic setup using google logins. +1. Configure a google OAuth2 project. See https://docs.microsoft.com/aspnet/core/security/authentication/social/google-logins for basic setup using google logins. 2. Update Startup.cs AddGoogle()'s options with ClientId and ClientSecret for your google app. 3. Run the app and click on the MyClaims tab, this should trigger a redirect to login. 4. Login via the Google button, this should redirect you to google. diff --git a/src/Security/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj b/src/Security/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj index 9808064e24..1753f9f548 100644 --- a/src/Security/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj +++ b/src/Security/test/AuthSamples.FunctionalTests/AuthSamples.FunctionalTests.csproj @@ -4,7 +4,7 @@ <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> <IsSampleProject>false</IsSampleProject> <PlatformTarget>AnyCPU</PlatformTarget> - <!-- Test asset publishing not working on arm64 https://github.com/aspnet/AspNetCore/issues/11205 --> + <!-- Test asset publishing not working on arm64 https://github.com/dotnet/aspnetcore/issues/11205 --> <SkipHelixArm>true</SkipHelixArm> </PropertyGroup> diff --git a/src/Security/test/AuthSamples.FunctionalTests/IdentityExternalClaimsTests.cs b/src/Security/test/AuthSamples.FunctionalTests/IdentityExternalClaimsTests.cs index 955a911486..e216b7d19b 100644 --- a/src/Security/test/AuthSamples.FunctionalTests/IdentityExternalClaimsTests.cs +++ b/src/Security/test/AuthSamples.FunctionalTests/IdentityExternalClaimsTests.cs @@ -29,7 +29,7 @@ namespace AuthSamples.FunctionalTests Assert.Equal(HttpStatusCode.OK, response.StatusCode); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/8387")] public async Task MyClaimsRedirectsToLoginPageWhenNotLoggedIn() { // Arrange & Act diff --git a/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netcoreapp.cs b/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netcoreapp.cs index dbd0a70349..1cf1fe4d3a 100644 --- a/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netcoreapp.cs +++ b/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netcoreapp.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Connections public partial class ConnectionBuilder : Microsoft.AspNetCore.Connections.IConnectionBuilder { public ConnectionBuilder(System.IServiceProvider applicationServices) { } - public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Connections.ConnectionDelegate Build() { throw null; } public Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware) { throw null; } } @@ -30,12 +30,12 @@ namespace Microsoft.AspNetCore.Connections public abstract partial class ConnectionContext : System.IAsyncDisposable { protected ConnectionContext() { } - public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract string ConnectionId { get; set; } public abstract Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get; } public abstract System.Collections.Generic.IDictionary<object, object> Items { get; set; } - public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.IO.Pipelines.IDuplexPipe Transport { get; set; } public virtual void Abort() { } public virtual void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { } @@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Connections { public ConnectionItems() { } public ConnectionItems(System.Collections.Generic.IDictionary<object, object> items) { } - public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } int System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Count { get { throw null; } } bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.IsReadOnly { get { throw null; } } object System.Collections.Generic.IDictionary<System.Object,System.Object>.this[object key] { get { throw null; } set { } } @@ -79,23 +79,23 @@ namespace Microsoft.AspNetCore.Connections public DefaultConnectionContext() { } public DefaultConnectionContext(string id) { } public DefaultConnectionContext(string id, System.IO.Pipelines.IDuplexPipe transport, System.IO.Pipelines.IDuplexPipe application) { } - public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } } public partial class FileHandleEndPoint : System.Net.EndPoint { public FileHandleEndPoint(ulong fileHandle, Microsoft.AspNetCore.Connections.FileHandleType fileHandleType) { } - public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum FileHandleType { @@ -123,6 +123,9 @@ namespace Microsoft.AspNetCore.Connections { System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.IConnectionListener> BindAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); } + public partial interface IMultiplexedConnectionListenerFactory : Microsoft.AspNetCore.Connections.IConnectionListenerFactory + { + } [System.FlagsAttribute] public enum TransferFormat { @@ -132,7 +135,16 @@ namespace Microsoft.AspNetCore.Connections public partial class UriEndPoint : System.Net.EndPoint { public UriEndPoint(System.Uri uri) { } - public System.Uri Uri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Uri Uri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override string ToString() { throw null; } + } +} +namespace Microsoft.AspNetCore.Connections.Abstractions.Features +{ + public partial interface IQuicCreateStreamFeature + { + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> StartBidirectionalStreamAsync(); + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> StartUnidirectionalStreamAsync(); } } namespace Microsoft.AspNetCore.Connections.Features @@ -184,6 +196,15 @@ namespace Microsoft.AspNetCore.Connections.Features { System.Buffers.MemoryPool<byte> MemoryPool { get; } } + public partial interface IQuicStreamFeature + { + bool IsUnidirectional { get; } + long StreamId { get; } + } + public partial interface IQuicStreamListenerFeature + { + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> AcceptAsync(); + } public partial interface ITlsHandshakeFeature { System.Security.Authentication.CipherAlgorithmType CipherAlgorithm { get; } diff --git a/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs b/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs index dbd0a70349..1cf1fe4d3a 100644 --- a/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs +++ b/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.0.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Connections public partial class ConnectionBuilder : Microsoft.AspNetCore.Connections.IConnectionBuilder { public ConnectionBuilder(System.IServiceProvider applicationServices) { } - public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Connections.ConnectionDelegate Build() { throw null; } public Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware) { throw null; } } @@ -30,12 +30,12 @@ namespace Microsoft.AspNetCore.Connections public abstract partial class ConnectionContext : System.IAsyncDisposable { protected ConnectionContext() { } - public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract string ConnectionId { get; set; } public abstract Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get; } public abstract System.Collections.Generic.IDictionary<object, object> Items { get; set; } - public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.IO.Pipelines.IDuplexPipe Transport { get; set; } public virtual void Abort() { } public virtual void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { } @@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Connections { public ConnectionItems() { } public ConnectionItems(System.Collections.Generic.IDictionary<object, object> items) { } - public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } int System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Count { get { throw null; } } bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.IsReadOnly { get { throw null; } } object System.Collections.Generic.IDictionary<System.Object,System.Object>.this[object key] { get { throw null; } set { } } @@ -79,23 +79,23 @@ namespace Microsoft.AspNetCore.Connections public DefaultConnectionContext() { } public DefaultConnectionContext(string id) { } public DefaultConnectionContext(string id, System.IO.Pipelines.IDuplexPipe transport, System.IO.Pipelines.IDuplexPipe application) { } - public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } } public partial class FileHandleEndPoint : System.Net.EndPoint { public FileHandleEndPoint(ulong fileHandle, Microsoft.AspNetCore.Connections.FileHandleType fileHandleType) { } - public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum FileHandleType { @@ -123,6 +123,9 @@ namespace Microsoft.AspNetCore.Connections { System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.IConnectionListener> BindAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); } + public partial interface IMultiplexedConnectionListenerFactory : Microsoft.AspNetCore.Connections.IConnectionListenerFactory + { + } [System.FlagsAttribute] public enum TransferFormat { @@ -132,7 +135,16 @@ namespace Microsoft.AspNetCore.Connections public partial class UriEndPoint : System.Net.EndPoint { public UriEndPoint(System.Uri uri) { } - public System.Uri Uri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Uri Uri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override string ToString() { throw null; } + } +} +namespace Microsoft.AspNetCore.Connections.Abstractions.Features +{ + public partial interface IQuicCreateStreamFeature + { + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> StartBidirectionalStreamAsync(); + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> StartUnidirectionalStreamAsync(); } } namespace Microsoft.AspNetCore.Connections.Features @@ -184,6 +196,15 @@ namespace Microsoft.AspNetCore.Connections.Features { System.Buffers.MemoryPool<byte> MemoryPool { get; } } + public partial interface IQuicStreamFeature + { + bool IsUnidirectional { get; } + long StreamId { get; } + } + public partial interface IQuicStreamListenerFeature + { + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> AcceptAsync(); + } public partial interface ITlsHandshakeFeature { System.Security.Authentication.CipherAlgorithmType CipherAlgorithm { get; } diff --git a/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs b/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs index dbd0a70349..1cf1fe4d3a 100644 --- a/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs +++ b/src/Servers/Connections.Abstractions/ref/Microsoft.AspNetCore.Connections.Abstractions.netstandard2.1.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Connections public partial class ConnectionBuilder : Microsoft.AspNetCore.Connections.IConnectionBuilder { public ConnectionBuilder(System.IServiceProvider applicationServices) { } - public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.IServiceProvider ApplicationServices { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Connections.ConnectionDelegate Build() { throw null; } public Microsoft.AspNetCore.Connections.IConnectionBuilder Use(System.Func<Microsoft.AspNetCore.Connections.ConnectionDelegate, Microsoft.AspNetCore.Connections.ConnectionDelegate> middleware) { throw null; } } @@ -30,12 +30,12 @@ namespace Microsoft.AspNetCore.Connections public abstract partial class ConnectionContext : System.IAsyncDisposable { protected ConnectionContext() { } - public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract string ConnectionId { get; set; } public abstract Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get; } public abstract System.Collections.Generic.IDictionary<object, object> Items { get; set; } - public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public virtual System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public abstract System.IO.Pipelines.IDuplexPipe Transport { get; set; } public virtual void Abort() { } public virtual void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { } @@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Connections { public ConnectionItems() { } public ConnectionItems(System.Collections.Generic.IDictionary<object, object> items) { } - public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } int System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.Count { get { throw null; } } bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.Object,System.Object>>.IsReadOnly { get { throw null; } } object System.Collections.Generic.IDictionary<System.Object,System.Object>.this[object key] { get { throw null; } set { } } @@ -79,23 +79,23 @@ namespace Microsoft.AspNetCore.Connections public DefaultConnectionContext() { } public DefaultConnectionContext(string id) { } public DefaultConnectionContext(string id, System.IO.Pipelines.IDuplexPipe transport, System.IO.Pipelines.IDuplexPipe application) { } - public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.IO.Pipelines.IDuplexPipe Application { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Threading.CancellationToken ConnectionClosed { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Net.EndPoint LocalEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.Net.EndPoint RemoteEndPoint { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public override System.IO.Pipelines.IDuplexPipe Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public override void Abort(Microsoft.AspNetCore.Connections.ConnectionAbortedException abortReason) { } public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } } public partial class FileHandleEndPoint : System.Net.EndPoint { public FileHandleEndPoint(ulong fileHandle, Microsoft.AspNetCore.Connections.FileHandleType fileHandleType) { } - public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public ulong FileHandle { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Connections.FileHandleType FileHandleType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public enum FileHandleType { @@ -123,6 +123,9 @@ namespace Microsoft.AspNetCore.Connections { System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.IConnectionListener> BindAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); } + public partial interface IMultiplexedConnectionListenerFactory : Microsoft.AspNetCore.Connections.IConnectionListenerFactory + { + } [System.FlagsAttribute] public enum TransferFormat { @@ -132,7 +135,16 @@ namespace Microsoft.AspNetCore.Connections public partial class UriEndPoint : System.Net.EndPoint { public UriEndPoint(System.Uri uri) { } - public System.Uri Uri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Uri Uri { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override string ToString() { throw null; } + } +} +namespace Microsoft.AspNetCore.Connections.Abstractions.Features +{ + public partial interface IQuicCreateStreamFeature + { + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> StartBidirectionalStreamAsync(); + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> StartUnidirectionalStreamAsync(); } } namespace Microsoft.AspNetCore.Connections.Features @@ -184,6 +196,15 @@ namespace Microsoft.AspNetCore.Connections.Features { System.Buffers.MemoryPool<byte> MemoryPool { get; } } + public partial interface IQuicStreamFeature + { + bool IsUnidirectional { get; } + long StreamId { get; } + } + public partial interface IQuicStreamListenerFeature + { + System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> AcceptAsync(); + } public partial interface ITlsHandshakeFeature { System.Security.Authentication.CipherAlgorithmType CipherAlgorithm { get; } diff --git a/src/Servers/Connections.Abstractions/src/Features/IQuicCreateStreamFeature.cs b/src/Servers/Connections.Abstractions/src/Features/IQuicCreateStreamFeature.cs new file mode 100644 index 0000000000..1de25e4313 --- /dev/null +++ b/src/Servers/Connections.Abstractions/src/Features/IQuicCreateStreamFeature.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.Connections.Abstractions.Features +{ + public interface IQuicCreateStreamFeature + { + ValueTask<ConnectionContext> StartUnidirectionalStreamAsync(); + ValueTask<ConnectionContext> StartBidirectionalStreamAsync(); + } +} diff --git a/src/Servers/Connections.Abstractions/src/Features/IQuicStreamFeature.cs b/src/Servers/Connections.Abstractions/src/Features/IQuicStreamFeature.cs new file mode 100644 index 0000000000..98c71b7a08 --- /dev/null +++ b/src/Servers/Connections.Abstractions/src/Features/IQuicStreamFeature.cs @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNetCore.Connections.Features +{ + public interface IQuicStreamFeature + { + bool IsUnidirectional { get; } + long StreamId { get; } + } +} diff --git a/src/Servers/Connections.Abstractions/src/Features/IQuicStreamListenerFeature.cs b/src/Servers/Connections.Abstractions/src/Features/IQuicStreamListenerFeature.cs new file mode 100644 index 0000000000..e9f63aeb36 --- /dev/null +++ b/src/Servers/Connections.Abstractions/src/Features/IQuicStreamListenerFeature.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.Connections.Features +{ + public interface IQuicStreamListenerFeature + { + ValueTask<ConnectionContext> AcceptAsync(); + } +} diff --git a/src/Servers/Connections.Abstractions/src/IMultiplexedConnectionListenerFactory.cs b/src/Servers/Connections.Abstractions/src/IMultiplexedConnectionListenerFactory.cs new file mode 100644 index 0000000000..65727b7ad8 --- /dev/null +++ b/src/Servers/Connections.Abstractions/src/IMultiplexedConnectionListenerFactory.cs @@ -0,0 +1,9 @@ +// 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. + +namespace Microsoft.AspNetCore.Connections +{ + public interface IMultiplexedConnectionListenerFactory : IConnectionListenerFactory + { + } +} diff --git a/src/Servers/Connections.Abstractions/src/UriEndPoint.cs b/src/Servers/Connections.Abstractions/src/UriEndPoint.cs index 0321d5af2d..7000b86611 100644 --- a/src/Servers/Connections.Abstractions/src/UriEndPoint.cs +++ b/src/Servers/Connections.Abstractions/src/UriEndPoint.cs @@ -24,5 +24,7 @@ namespace Microsoft.AspNetCore.Connections /// The <see cref="System.Uri"/> defining the <see cref="EndPoint"/>. /// </summary> public Uri Uri { get; } + + public override string ToString() => Uri.ToString(); } } diff --git a/src/Servers/HttpSys/HttpSysServer.sln b/src/Servers/HttpSys/HttpSysServer.sln index bdd6b9c522..75f0aad286 100644 --- a/src/Servers/HttpSys/HttpSysServer.sln +++ b/src/Servers/HttpSys/HttpSysServer.sln @@ -24,7 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution version.xml = version.xml EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "samples\TestClient\TestClient.csproj", "{8B828433-B333-4C19-96AE-00BFFF9D8841}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestClient", "samples\TestClient\TestClient.csproj", "{8B828433-B333-4C19-96AE-00BFFF9D8841}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SelfHostServer", "samples\SelfHostServer\SelfHostServer.csproj", "{1236F93A-AC5C-4A77-9477-C88F040151CA}" EndProject @@ -72,6 +72,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Connec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QueueSharing", "samples\QueueSharing\QueueSharing.csproj", "{9B58DF76-DC6D-4728-86B7-40087BDDC897}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets", "..\Kestrel\Transport.Sockets\src\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj", "{33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore", "..\..\DefaultBuilder\src\Microsoft.AspNetCore.csproj", "{E8880B06-7172-4995-893D-13E87AF00E7B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -318,6 +322,30 @@ Global {9B58DF76-DC6D-4728-86B7-40087BDDC897}.Release|Mixed Platforms.Build.0 = Release|Any CPU {9B58DF76-DC6D-4728-86B7-40087BDDC897}.Release|x86.ActiveCfg = Release|Any CPU {9B58DF76-DC6D-4728-86B7-40087BDDC897}.Release|x86.Build.0 = Release|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Debug|x86.Build.0 = Debug|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Release|Any CPU.Build.0 = Release|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Release|x86.ActiveCfg = Release|Any CPU + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB}.Release|x86.Build.0 = Release|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Debug|x86.ActiveCfg = Debug|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Debug|x86.Build.0 = Debug|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Release|Any CPU.Build.0 = Release|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Release|x86.ActiveCfg = Release|Any CPU + {E8880B06-7172-4995-893D-13E87AF00E7B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -344,6 +372,8 @@ Global {D93575B3-BFA3-4523-B060-D268D6A0A66B} = {4DA3C456-5050-4AC0-A554-795F6DEC8660} {00A88B8D-D539-45DD-B071-1E955AF89A4A} = {4DA3C456-5050-4AC0-A554-795F6DEC8660} {9B58DF76-DC6D-4728-86B7-40087BDDC897} = {3A1E31E3-2794-4CA3-B8E2-253E96BDE514} + {33CF53ED-A4BC-4EAA-9EA7-EF5E748A03BB} = {4DA3C456-5050-4AC0-A554-795F6DEC8660} + {E8880B06-7172-4995-893D-13E87AF00E7B} = {4DA3C456-5050-4AC0-A554-795F6DEC8660} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {34B42B42-FA09-41AB-9216-14073990C504} diff --git a/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp.cs b/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp.cs index 31f097495b..98e383a676 100644 --- a/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp.cs +++ b/src/Servers/HttpSys/ref/Microsoft.AspNetCore.Server.HttpSys.netcoreapp.cs @@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { internal AuthenticationManager() { } public bool AllowAnonymous { get { throw null; } set { } } + public bool AutomaticAuthentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Server.HttpSys.AuthenticationSchemes Schemes { get { throw null; } set { } } } [System.FlagsAttribute] @@ -50,20 +51,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys public partial class HttpSysOptions { public HttpSysOptions() { } - public bool AllowSynchronousIO { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Server.HttpSys.AuthenticationManager Authentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Server.HttpSys.ClientCertificateMethod ClientCertificateMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool EnableResponseCaching { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowSynchronousIO { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Server.HttpSys.AuthenticationManager Authentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.HttpSys.ClientCertificateMethod ClientCertificateMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool EnableResponseCaching { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Server.HttpSys.Http503VerbosityLevel Http503Verbosity { get { throw null; } set { } } - public int MaxAccepts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int MaxAccepts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public long? MaxConnections { get { throw null; } set { } } public long? MaxRequestBodySize { get { throw null; } set { } } public long RequestQueueLimit { get { throw null; } set { } } - public Microsoft.AspNetCore.Server.HttpSys.RequestQueueMode RequestQueueMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Server.HttpSys.RequestQueueMode RequestQueueMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string RequestQueueName { get { throw null; } set { } } - public bool ThrowWriteExceptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Server.HttpSys.TimeoutManager Timeouts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Server.HttpSys.UrlPrefixCollection UrlPrefixes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool ThrowWriteExceptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Server.HttpSys.TimeoutManager Timeouts { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.HttpSys.UrlPrefixCollection UrlPrefixes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial interface IHttpSysRequestInfoFeature { @@ -88,13 +89,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys public partial class UrlPrefix { internal UrlPrefix() { } - public string FullPrefix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsHttps { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Port { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int PortValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string FullPrefix { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Host { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsHttps { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Port { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int PortValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.Server.HttpSys.UrlPrefix Create(string prefix) { throw null; } public static Microsoft.AspNetCore.Server.HttpSys.UrlPrefix Create(string scheme, string host, int? portValue, string path) { throw null; } public static Microsoft.AspNetCore.Server.HttpSys.UrlPrefix Create(string scheme, string host, string port, string path) { throw null; } diff --git a/src/Servers/HttpSys/samples/SelfHostServer/Program.cs b/src/Servers/HttpSys/samples/SelfHostServer/Program.cs new file mode 100644 index 0000000000..df39ba8da8 --- /dev/null +++ b/src/Servers/HttpSys/samples/SelfHostServer/Program.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.HttpSys; +using Microsoft.Extensions.Hosting; + +namespace SelfHostServer +{ + public static class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup<Startup>() + .UseHttpSys(options => + { + options.UrlPrefixes.Add("http://localhost:5000"); + // This is a pre-configured IIS express port. See the PackageTags in the csproj. + options.UrlPrefixes.Add("https://localhost:44319"); + options.Authentication.Schemes = AuthenticationSchemes.None; + options.Authentication.AllowAnonymous = true; + }); + }); + } +} diff --git a/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj b/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj index 35450964c9..a824a8daee 100644 --- a/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj +++ b/src/Servers/HttpSys/samples/SelfHostServer/SelfHostServer.csproj @@ -12,7 +12,9 @@ </PropertyGroup> <ItemGroup> + <Reference Include="Microsoft.AspNetCore" /> <Reference Include="Microsoft.AspNetCore.Server.HttpSys" /> + <Reference Include="Microsoft.Extensions.Hosting" /> <Reference Include="Microsoft.Extensions.Logging.Console" /> </ItemGroup> </Project> diff --git a/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs b/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs index 42f6d11f81..28665f54dc 100644 --- a/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs +++ b/src/Servers/HttpSys/samples/SelfHostServer/Startup.cs @@ -1,3 +1,6 @@ +// 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 Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -28,23 +31,5 @@ namespace SelfHostServer await context.Response.WriteAsync("Hello world from " + context.Request.Host + " at " + DateTime.Now); }); } - - public static void Main(string[] args) - { - var host = new WebHostBuilder() - .ConfigureLogging(factory => factory.AddConsole()) - .UseStartup<Startup>() - .UseHttpSys(options => - { - options.UrlPrefixes.Add("http://localhost:5000"); - // This is a pre-configured IIS express port. See the PackageTags in the csproj. - options.UrlPrefixes.Add("https://localhost:44319"); - options.Authentication.Schemes = AuthenticationSchemes.None; - options.Authentication.AllowAnonymous = true; - }) - .Build(); - - host.Run(); - } } } diff --git a/src/Servers/HttpSys/samples/TestClient/App.config b/src/Servers/HttpSys/samples/TestClient/App.config deleted file mode 100644 index 2d2a12d81b..0000000000 --- a/src/Servers/HttpSys/samples/TestClient/App.config +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<configuration> - <startup> - <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/> - </startup> -</configuration> diff --git a/src/Servers/HttpSys/samples/TestClient/Program.cs b/src/Servers/HttpSys/samples/TestClient/Program.cs index f57945de42..f81dc83833 100644 --- a/src/Servers/HttpSys/samples/TestClient/Program.cs +++ b/src/Servers/HttpSys/samples/TestClient/Program.cs @@ -11,20 +11,45 @@ namespace TestClient public class Program { private const string Address = - // "http://localhost:5000/public/1kb.txt"; - "https://localhost:9090/public/1kb.txt"; + "http://localhost:5000/public/1kb.txt"; + // "https://localhost:9090/public/1kb.txt"; public static void Main(string[] args) { - WebRequestHandler handler = new WebRequestHandler(); - handler.ServerCertificateValidationCallback = (_, __, ___, ____) => true; + Console.WriteLine("Ready"); + Console.ReadKey(); + + var handler = new HttpClientHandler(); + handler.MaxConnectionsPerServer = 500; + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; // handler.UseDefaultCredentials = true; - handler.Credentials = new NetworkCredential(@"redmond\chrross", "passwird"); HttpClient client = new HttpClient(handler); - /* + RunParallelRequests(client); + + // RunManualRequests(client); + + // RunWebSocketClient().Wait(); + + Console.WriteLine("Done"); + // Console.ReadKey(); + } + + private static void RunManualRequests(HttpClient client) + { + while (true) + { + Console.WriteLine("Press any key to send request"); + Console.ReadKey(); + var result = client.GetAsync(Address).Result; + Console.WriteLine(result); + } + } + + private static void RunParallelRequests(HttpClient client) + { int completionCount = 0; - int iterations = 30000; + int iterations = 100000; for (int i = 0; i < iterations; i++) { client.GetAsync(Address) @@ -34,19 +59,7 @@ namespace TestClient while (completionCount < iterations) { Thread.Sleep(10); - }*/ - - while (true) - { - Console.WriteLine("Press any key to send request"); - Console.ReadKey(); - var result = client.GetAsync(Address).Result; - Console.WriteLine(result); } - - // RunWebSocketClient().Wait(); - // Console.WriteLine("Done"); - // Console.ReadKey(); } public static async Task RunWebSocketClient() diff --git a/src/Servers/HttpSys/samples/TestClient/Properties/AssemblyInfo.cs b/src/Servers/HttpSys/samples/TestClient/Properties/AssemblyInfo.cs deleted file mode 100644 index 249372ae2d..0000000000 --- a/src/Servers/HttpSys/samples/TestClient/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. -// All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR -// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING -// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF -// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR -// NON-INFRINGEMENT. -// See the Apache 2 License for the specific language governing -// permissions and limitations under the License. - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TestClient")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TestClient")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("8db62eb3-48c0-4049-b33e-271c738140a0")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("0.5")] -[assembly: AssemblyVersion("0.5")] -[assembly: AssemblyFileVersion("0.5.40117.0")] diff --git a/src/Servers/HttpSys/samples/TestClient/TestClient.csproj b/src/Servers/HttpSys/samples/TestClient/TestClient.csproj index c92be92bc8..6d5bb6e338 100644 --- a/src/Servers/HttpSys/samples/TestClient/TestClient.csproj +++ b/src/Servers/HttpSys/samples/TestClient/TestClient.csproj @@ -1,64 +1,13 @@ - -<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProjectGuid>{8B828433-B333-4C19-96AE-00BFFF9D8841}</ProjectGuid> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> <OutputType>Exe</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>TestClient</RootNamespace> - <AssemblyName>TestClient</AssemblyName> - <TargetFrameworkVersion>v4.6</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <RestorePackages>true</RestorePackages> - <TargetFrameworkProfile /> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> + <StartupObject>TestClient.Program</StartupObject> </PropertyGroup> + <ItemGroup> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Net.Http" /> - <Reference Include="System.Net.Http.WebRequest" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Xml" /> + <Reference Include="Microsoft.Extensions.Logging.Console" /> </ItemGroup> - <ItemGroup> - <Compile Include="Program.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - </ItemGroup> - <ItemGroup> - <None Include="App.config" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> - <Target Name="Pack" /> - <!-- To modify your build process, add your task inside one of the targets below and uncomment it. - Other similar extension points exist, see Microsoft.Common.targets. - <Target Name="BeforeBuild"> - </Target> - <Target Name="AfterBuild"> - </Target> - --> -</Project> \ No newline at end of file + +</Project> diff --git a/src/Servers/HttpSys/src/AsyncAcceptContext.cs b/src/Servers/HttpSys/src/AsyncAcceptContext.cs index 4c0cd86756..5908322598 100644 --- a/src/Servers/HttpSys/src/AsyncAcceptContext.cs +++ b/src/Servers/HttpSys/src/AsyncAcceptContext.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -18,8 +17,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys private TaskCompletionSource<RequestContext> _tcs; private HttpSysListener _server; private NativeRequestContext _nativeRequestContext; - private const int DefaultBufferSize = 4096; - private const int AlignmentPadding = 8; internal AsyncAcceptContext(HttpSysListener server) { @@ -192,32 +189,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys { _nativeRequestContext?.ReleasePins(); _nativeRequestContext?.Dispose(); - //Debug.Assert(size != 0, "unexpected size"); // We can't reuse overlapped objects - uint newSize = size.HasValue ? size.Value : DefaultBufferSize; - var backingBuffer = new byte[newSize + AlignmentPadding]; - var boundHandle = Server.RequestQueue.BoundHandle; var nativeOverlapped = new SafeNativeOverlapped(boundHandle, - boundHandle.AllocateNativeOverlapped(IOCallback, this, backingBuffer)); + boundHandle.AllocateNativeOverlapped(IOCallback, this, pinData: null)); - var requestAddress = Marshal.UnsafeAddrOfPinnedArrayElement(backingBuffer, 0); - - // TODO: - // Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors - // are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on - // virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In - // these cases the buffer alignment may cause reading values at invalid offset. Setting buffer - // alignment to 0 for now. - // - // _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07); - - var bufferAlignment = 0; - - var nativeRequest = (HttpApiTypes.HTTP_REQUEST*)(requestAddress + bufferAlignment); // nativeRequest - _nativeRequestContext = new NativeRequestContext(nativeOverlapped, bufferAlignment, nativeRequest, backingBuffer, requestId); + _nativeRequestContext = new NativeRequestContext(nativeOverlapped, Server.MemoryPool, size, requestId); } public object AsyncState diff --git a/src/Servers/HttpSys/src/AuthenticationManager.cs b/src/Servers/HttpSys/src/AuthenticationManager.cs index 29f5a3495a..9b54f0ab0f 100644 --- a/src/Servers/HttpSys/src/AuthenticationManager.cs +++ b/src/Servers/HttpSys/src/AuthenticationManager.cs @@ -45,12 +45,22 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + /// <summary> + /// Indicates if anonymous requests will be surfaced to the application or challenged by the server. + /// The default value is true. + /// </summary> public bool AllowAnonymous { get { return _allowAnonymous; } set { _allowAnonymous = value; } } + /// <summary> + /// If true the server should set HttpContext.User. If false the server will only provide an + /// identity when explicitly requested by the AuthenticationScheme. The default is true. + /// </summary> + public bool AutomaticAuthentication { get; set; } = true; + internal void SetUrlGroupSecurity(UrlGroup urlGroup) { Debug.Assert(_urlGroup == null, "SetUrlGroupSecurity called more than once."); diff --git a/src/Servers/HttpSys/src/FeatureContext.cs b/src/Servers/HttpSys/src/FeatureContext.cs index 7cce609f3e..23f76ff8c9 100644 --- a/src/Servers/HttpSys/src/FeatureContext.cs +++ b/src/Servers/HttpSys/src/FeatureContext.cs @@ -35,7 +35,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys IHttpRequestIdentifierFeature, IHttpMaxRequestBodySizeFeature, IHttpBodyControlFeature, - IHttpSysRequestInfoFeature + IHttpSysRequestInfoFeature, + IHttpResponseTrailersFeature, + IHttpResetFeature { private RequestContext _requestContext; private IFeatureCollection _features; @@ -63,6 +65,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys private PipeWriter _pipeWriter; private bool _bodyCompleted; private IHeaderDictionary _responseHeaders; + private IHeaderDictionary _responseTrailers; private Fields _initializedFields; @@ -85,7 +88,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys _query = Request.QueryString; _rawTarget = Request.RawUrl; _scheme = Request.Scheme; - _user = _requestContext.User; + + if (requestContext.Server.Options.Authentication.AutomaticAuthentication) + { + _user = _requestContext.User; + } _responseStream = new ResponseStream(requestContext.Response.Body, OnResponseStart); _responseHeaders = Response.Headers; @@ -174,23 +181,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (IsNotInitialized(Fields.Protocol)) { - var protocol = Request.ProtocolVersion; - if (protocol == Constants.V2) - { - _httpProtocolVersion = "HTTP/2"; - } - else if (protocol == Constants.V1_1) - { - _httpProtocolVersion = "HTTP/1.1"; - } - else if (protocol == Constants.V1_0) - { - _httpProtocolVersion = "HTTP/1.0"; - } - else - { - _httpProtocolVersion = "HTTP/" + protocol.ToString(2); - } + _httpProtocolVersion = Request.ProtocolVersion.GetHttpProtocolVersion(); SetInitialized(Fields.Protocol); } return _httpProtocolVersion; @@ -358,6 +349,24 @@ namespace Microsoft.AspNetCore.Server.HttpSys return Request.IsHttps ? this : null; } + internal IHttpResponseTrailersFeature GetResponseTrailersFeature() + { + if (Request.ProtocolVersion >= HttpVersion.Version20 && HttpApi.SupportsTrailers) + { + return this; + } + return null; + } + + internal IHttpResetFeature GetResetFeature() + { + if (Request.ProtocolVersion >= HttpVersion.Version20 && HttpApi.SupportsReset) + { + return this; + } + return null; + } + /* TODO: https://github.com/aspnet/HttpSysServer/issues/231 byte[] ITlsTokenBindingFeature.GetProvidedTokenBindingId() => Request.GetProvidedTokenBindingId(); @@ -401,7 +410,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys set { _responseHeaders = value; } } - bool IHttpResponseFeature.HasStarted => Response.HasStarted; + bool IHttpResponseFeature.HasStarted => _responseStarted; void IHttpResponseFeature.OnStarting(Func<object, Task> callback, object state) { @@ -456,6 +465,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys Task IHttpResponseBodyFeature.CompleteAsync() => CompleteAsync(); + void IHttpResetFeature.Reset(int errorCode) + { + _requestContext.SetResetCode(errorCode); + _requestContext.Abort(); + } + internal async Task CompleteAsync() { if (!_responseStarted) @@ -559,6 +574,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys IReadOnlyDictionary<int, ReadOnlyMemory<byte>> IHttpSysRequestInfoFeature.RequestInfo => Request.RequestInfo; + IHeaderDictionary IHttpResponseTrailersFeature.Trailers + { + get => _responseTrailers ??= Response.Trailers; + set => _responseTrailers = value; + } + internal async Task OnResponseStart() { if (_responseStarted) diff --git a/src/Servers/HttpSys/src/HttpSysListener.cs b/src/Servers/HttpSys/src/HttpSysListener.cs index 24f6c61955..c08517595c 100644 --- a/src/Servers/HttpSys/src/HttpSysListener.cs +++ b/src/Servers/HttpSys/src/HttpSysListener.cs @@ -2,6 +2,7 @@ // 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.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; @@ -32,6 +33,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys // 0.5 seconds per request. Respond with a 400 Bad Request. private const int UnknownHeaderLimit = 1000; + internal MemoryPool<byte> MemoryPool { get; } = SlabMemoryPoolFactory.Create(); + private volatile State _state; // m_State is set only within lock blocks, but often read outside locks. private ServerSession _serverSession; @@ -61,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys Options = options; - Logger = LogHelper.CreateLogger(loggerFactory, typeof(HttpSysListener)); + Logger = loggerFactory.CreateLogger<HttpSysListener>(); _state = State.Stopped; _internalLock = new object(); @@ -89,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys _requestQueue?.Dispose(); _urlGroup?.Dispose(); _serverSession?.Dispose(); - LogHelper.LogException(Logger, ".Ctor", exception); + Logger.LogError(0, exception, ".Ctor"); throw; } } @@ -132,7 +135,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { CheckDisposed(); - LogHelper.LogInfo(Logger, "Start"); + Logger.LogTrace("Starting the listener."); // Make sure there are no race conditions between Start/Stop/Abort/Close/Dispose. // Start needs to setup all resources. Abort/Stop must not interfere while Start is @@ -174,7 +177,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys // Make sure the HttpListener instance can't be used if Start() failed. _state = State.Disposed; DisposeInternal(); - LogHelper.LogException(Logger, "Start", exception); + Logger.LogError(0, exception, "Start"); throw; } } @@ -192,6 +195,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys return; } + Logger.LogTrace("Stopping the listener."); + // If this instance created the queue then remove the URL prefixes before shutting down. if (_requestQueue.Created) { @@ -205,7 +210,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception exception) { - LogHelper.LogException(Logger, "Stop", exception); + Logger.LogError(0, exception, "Stop"); throw; } } @@ -233,14 +238,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys { return; } - LogHelper.LogInfo(Logger, "Dispose"); + Logger.LogTrace("Disposing the listener."); Stop(); DisposeInternal(); } catch (Exception exception) { - LogHelper.LogException(Logger, "Dispose", exception); + Logger.LogError(0, exception, "Dispose"); throw; } finally @@ -295,7 +300,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception exception) { - LogHelper.LogException(Logger, "GetContextAsync", exception); + Logger.LogError(0, exception, "GetContextAsync"); throw; } diff --git a/src/Servers/HttpSys/src/LogHelper.cs b/src/Servers/HttpSys/src/LogHelper.cs deleted file mode 100644 index 2a9345d624..0000000000 --- a/src/Servers/HttpSys/src/LogHelper.cs +++ /dev/null @@ -1,106 +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. - -using System; -using System.Diagnostics; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Server.HttpSys -{ - internal static class LogHelper - { - internal static ILogger CreateLogger(ILoggerFactory factory, Type type) - { - if (factory == null) - { - return null; - } - - return factory.CreateLogger(type.FullName); - } - - internal static void LogInfo(ILogger logger, string data) - { - if (logger == null) - { - Debug.WriteLine(data); - } - else - { - logger.LogInformation(data); - } - } - - internal static void LogWarning(ILogger logger, string data) - { - if (logger == null) - { - Debug.WriteLine(data); - } - else - { - logger.LogWarning(data); - } - } - - internal static void LogDebug(ILogger logger, string data) - { - if (logger == null) - { - Debug.WriteLine(data); - } - else - { - logger.LogDebug(data); - } - } - - internal static void LogDebug(ILogger logger, string location, string data) - { - if (logger == null) - { - Debug.WriteLine(data); - } - else - { - logger.LogDebug(location + "; " + data); - } - } - - internal static void LogDebug(ILogger logger, string location, Exception exception) - { - if (logger == null) - { - Debug.WriteLine(location + Environment.NewLine + exception.ToString()); - } - else - { - logger.LogDebug(0, exception, location); - } - } - - internal static void LogException(ILogger logger, string location, Exception exception) - { - if (logger == null) - { - Debug.WriteLine(location + Environment.NewLine + exception.ToString()); - } - else - { - logger.LogError(0, exception, location); - } - } - - internal static void LogError(ILogger logger, string location, string message) - { - if (logger == null) - { - Debug.WriteLine(message); - } - else - { - logger.LogError(location + "; " + message); - } - } - } -} diff --git a/src/Servers/HttpSys/src/MessagePump.cs b/src/Servers/HttpSys/src/MessagePump.cs index 9917e69872..c2960f75f9 100644 --- a/src/Servers/HttpSys/src/MessagePump.cs +++ b/src/Servers/HttpSys/src/MessagePump.cs @@ -2,16 +2,18 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Diagnostics.Contracts; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.HttpSys.Internal; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Microsoft.AspNetCore.HttpSys.Internal; namespace Microsoft.AspNetCore.Server.HttpSys { @@ -45,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } _options = options.Value; Listener = new HttpSysListener(_options, loggerFactory); - _logger = LogHelper.CreateLogger(loggerFactory, typeof(MessagePump)); + _logger = loggerFactory.CreateLogger<MessagePump>(); if (_options.Authentication.Schemes != AuthenticationSchemes.None) { @@ -74,49 +76,40 @@ namespace Microsoft.AspNetCore.Server.HttpSys } var hostingUrlsPresent = _serverAddresses.Addresses.Count > 0; + var serverAddressCopy = _serverAddresses.Addresses.ToList(); + _serverAddresses.Addresses.Clear(); if (_serverAddresses.PreferHostingUrls && hostingUrlsPresent) { if (_options.UrlPrefixes.Count > 0) { - LogHelper.LogWarning(_logger, $"Overriding endpoints added to {nameof(HttpSysOptions.UrlPrefixes)} since {nameof(IServerAddressesFeature.PreferHostingUrls)} is set to true." + + _logger.LogWarning($"Overriding endpoints added to {nameof(HttpSysOptions.UrlPrefixes)} since {nameof(IServerAddressesFeature.PreferHostingUrls)} is set to true." + $" Binding to address(es) '{string.Join(", ", _serverAddresses.Addresses)}' instead. "); Listener.Options.UrlPrefixes.Clear(); } - foreach (var value in _serverAddresses.Addresses) - { - Listener.Options.UrlPrefixes.Add(value); - } + UpdateUrlPrefixes(serverAddressCopy); } else if (_options.UrlPrefixes.Count > 0) { if (hostingUrlsPresent) { - LogHelper.LogWarning(_logger, $"Overriding address(es) '{string.Join(", ", _serverAddresses.Addresses)}'. " + + _logger.LogWarning($"Overriding address(es) '{string.Join(", ", _serverAddresses.Addresses)}'. " + $"Binding to endpoints added to {nameof(HttpSysOptions.UrlPrefixes)} instead."); _serverAddresses.Addresses.Clear(); } - foreach (var prefix in _options.UrlPrefixes) - { - _serverAddresses.Addresses.Add(prefix.FullPrefix); - } } else if (hostingUrlsPresent) { - foreach (var value in _serverAddresses.Addresses) - { - Listener.Options.UrlPrefixes.Add(value); - } + UpdateUrlPrefixes(serverAddressCopy); } else if (Listener.RequestQueue.Created) { - LogHelper.LogDebug(_logger, $"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default."); + _logger.LogDebug($"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default."); - _serverAddresses.Addresses.Add(Constants.DefaultServerAddress); Listener.Options.UrlPrefixes.Add(Constants.DefaultServerAddress); } // else // Attaching to an existing queue, don't add a default. @@ -130,6 +123,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys Listener.Start(); + // Update server addresses after we start listening as port 0 + // needs to be selected at the point of binding. + foreach (var prefix in _options.UrlPrefixes) + { + _serverAddresses.Addresses.Add(prefix.FullPrefix); + } + ActivateRequestProcessingLimits(); return Task.CompletedTask; @@ -143,6 +143,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + private void UpdateUrlPrefixes(IList<string> serverAddressCopy) + { + foreach (var value in serverAddressCopy) + { + Listener.Options.UrlPrefixes.Add(value); + } + } + // The message pump. // When we start listening for the next request on one thread, we may need to be sure that the // completion continues on another thread as to not block the current request processing. @@ -163,11 +171,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys Contract.Assert(Stopping); if (Stopping) { - LogHelper.LogDebug(_logger, "ListenForNextRequestAsync-Stopping", exception); + _logger.LogDebug(0, exception, "ListenForNextRequestAsync-Stopping"); } else { - LogHelper.LogException(_logger, "ListenForNextRequestAsync", exception); + _logger.LogError(0, exception, "ListenForNextRequestAsync"); } continue; } @@ -179,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { // Request processing failed to be queued in threadpool // Log the error message, release throttle and move on - LogHelper.LogException(_logger, "ProcessRequestAsync", ex); + _logger.LogError(0, ex, "ProcessRequestAsync"); } } Interlocked.Decrement(ref _acceptorCounts); @@ -216,17 +224,22 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception ex) { - LogHelper.LogException(_logger, "ProcessRequestAsync", ex); + _logger.LogError(0, ex, "ProcessRequestAsync"); _application.DisposeContext(context, ex); if (requestContext.Response.HasStarted) { + // HTTP/2 INTERNAL_ERROR = 0x2 https://tools.ietf.org/html/rfc7540#section-7 + // Otherwise the default is Cancel = 0x8. + requestContext.SetResetCode(2); requestContext.Abort(); } else { // We haven't sent a response yet, try to send a 500 Internal Server Error requestContext.Response.Headers.IsReadOnly = false; + requestContext.Response.Trailers.IsReadOnly = false; requestContext.Response.Headers.Clear(); + requestContext.Response.Trailers.Clear(); SetFatalResponse(requestContext, 500); } } @@ -234,14 +247,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (Interlocked.Decrement(ref _outstandingRequests) == 0 && Stopping) { - LogHelper.LogInfo(_logger, "All requests drained."); + _logger.LogInformation("All requests drained."); _shutdownSignal.TrySetResult(0); } } } catch (Exception ex) { - LogHelper.LogException(_logger, "ProcessRequestAsync", ex); + _logger.LogError(0, ex, "ProcessRequestAsync"); requestContext.Abort(); } } @@ -261,7 +274,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (Interlocked.Exchange(ref _shutdownSignalCompleted, 1) == 0) { - LogHelper.LogInfo(_logger, "Canceled, terminating " + _outstandingRequests + " request(s)."); + _logger.LogInformation("Canceled, terminating " + _outstandingRequests + " request(s)."); _shutdownSignal.TrySetResult(null); } }); @@ -279,7 +292,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys // Wait for active requests to drain if (_outstandingRequests > 0) { - LogHelper.LogInfo(_logger, "Stopping, waiting for " + _outstandingRequests + " request(s) to drain."); + _logger.LogInformation("Stopping, waiting for " + _outstandingRequests + " request(s) to drain."); RegisterCancelation(); } else diff --git a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj index c41c4af7a1..2e57c61ce8 100644 --- a/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj +++ b/src/Servers/HttpSys/src/Microsoft.AspNetCore.Server.HttpSys.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <Description>ASP.NET Core HTTP server that uses the Windows HTTP Server API.</Description> @@ -13,6 +13,10 @@ <ItemGroup> <Compile Include="$(SharedSourceRoot)HttpSys\**\*.cs" /> + <Compile Include="$(SharedSourceRoot)Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" /> + </ItemGroup> + + <ItemGroup> </ItemGroup> <ItemGroup> diff --git a/src/Servers/HttpSys/src/NativeInterop/DisconnectListener.cs b/src/Servers/HttpSys/src/NativeInterop/DisconnectListener.cs index ecef12b989..2695c04e53 100644 --- a/src/Servers/HttpSys/src/NativeInterop/DisconnectListener.cs +++ b/src/Servers/HttpSys/src/NativeInterop/DisconnectListener.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Win32Exception exception) { - LogHelper.LogException(_logger, "GetConnectionToken", exception); + _logger.LogError(0, exception, "GetConnectionToken"); return CancellationToken.None; } } @@ -54,12 +54,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys { // Race condition on creation has no side effects var cancellation = new ConnectionCancellation(this); - return _connectionCancellationTokens.GetOrAdd(connectionId, cancellation); + return _connectionCancellationTokens.GetOrAdd(connectionId, cancellation); } private unsafe CancellationToken CreateDisconnectToken(ulong connectionId) { - LogHelper.LogDebug(_logger, "CreateDisconnectToken", "Registering connection for disconnect for connection ID: " + connectionId); + _logger.LogDebug("CreateDisconnectToken; Registering connection for disconnect for connection ID: " + connectionId); // Create a nativeOverlapped callback so we can register for disconnect callback var cts = new CancellationTokenSource(); @@ -70,8 +70,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys nativeOverlapped = new SafeNativeOverlapped(boundHandle, boundHandle.AllocateNativeOverlapped( (errorCode, numBytes, overlappedPtr) => { - LogHelper.LogDebug(_logger, "CreateDisconnectToken", "http.sys disconnect callback fired for connection ID: " + connectionId); - + _logger.LogDebug("CreateDisconnectToken; http.sys disconnect callback fired for connection ID: " + connectionId); + // Free the overlapped nativeOverlapped.Dispose(); @@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (AggregateException exception) { - LogHelper.LogException(_logger, "CreateDisconnectToken Callback", exception); + _logger.LogError(0, exception, "CreateDisconnectToken Callback"); } }, null, null)); @@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys catch (Win32Exception exception) { statusCode = (uint)exception.NativeErrorCode; - LogHelper.LogException(_logger, "CreateDisconnectToken", exception); + _logger.LogError(0, exception, "CreateDisconnectToken"); } if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING && @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys nativeOverlapped.Dispose(); ConnectionCancellation ignored; _connectionCancellationTokens.TryRemove(connectionId, out ignored); - LogHelper.LogDebug(_logger, "HttpWaitForDisconnectEx", new Win32Exception((int)statusCode)); + _logger.LogDebug(0, new Win32Exception((int)statusCode), "HttpWaitForDisconnectEx"); cts.Cancel(); } diff --git a/src/Servers/HttpSys/src/NativeInterop/HttpApi.cs b/src/Servers/HttpSys/src/NativeInterop/HttpApi.cs index c4e23d3b3d..6781465bc2 100644 --- a/src/Servers/HttpSys/src/NativeInterop/HttpApi.cs +++ b/src/Servers/HttpSys/src/NativeInterop/HttpApi.cs @@ -70,6 +70,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)] internal static extern unsafe uint HttpCloseRequestQueue(IntPtr pReqQueueHandle); + internal delegate uint HttpSetRequestPropertyInvoker(SafeHandle requestQueueHandle, ulong requestId, HTTP_REQUEST_PROPERTY propertyId, void* input, uint inputSize, IntPtr overlapped); private static HTTPAPI_VERSION version; @@ -106,6 +107,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + internal static SafeLibraryHandle HttpApiModule { get; private set; } + internal static HttpSetRequestPropertyInvoker HttpSetRequestProperty { get; private set; } + internal static bool SupportsTrailers { get; private set; } + internal static bool SupportsReset { get; private set; } + static HttpApi() { InitHttpApi(2, 0); @@ -119,6 +125,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys var statusCode = HttpInitialize(version, (uint)HTTP_FLAGS.HTTP_INITIALIZE_SERVER, null); supported = statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS; + + if (supported) + { + HttpApiModule = SafeLibraryHandle.Open(HTTPAPI); + HttpSetRequestProperty = HttpApiModule.GetProcAddress<HttpSetRequestPropertyInvoker>("HttpSetRequestProperty", throwIfNotFound: false); + + SupportsReset = HttpSetRequestProperty != null; + // Trailers support was added in the same release as Reset, but there's no method we can export to check it directly. + SupportsTrailers = SupportsReset; + } } private static volatile bool supported; diff --git a/src/Servers/HttpSys/src/NativeInterop/SafeLibraryHandle.cs b/src/Servers/HttpSys/src/NativeInterop/SafeLibraryHandle.cs new file mode 100644 index 0000000000..bf3254c6d6 --- /dev/null +++ b/src/Servers/HttpSys/src/NativeInterop/SafeLibraryHandle.cs @@ -0,0 +1,103 @@ +// 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.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using System.Security; +using Microsoft.Win32.SafeHandles; + +namespace Microsoft.AspNetCore.Server.HttpSys +{ + /// <summary> + /// Represents a handle to a Windows module (DLL). + /// </summary> + internal unsafe sealed class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid + { + // Called by P/Invoke when returning SafeHandles + private SafeLibraryHandle() + : base(ownsHandle: true) + { + } + + /// <summary> + /// Returns a value stating whether the library exports a given proc. + /// </summary> + public bool DoesProcExist(string lpProcName) + { + IntPtr pfnProc = UnsafeNativeMethods.GetProcAddress(this, lpProcName); + return (pfnProc != IntPtr.Zero); + } + + /// <summary> + /// Gets a delegate pointing to a given export from this library. + /// </summary> + public TDelegate GetProcAddress<TDelegate>(string lpProcName, bool throwIfNotFound = true) where TDelegate : class + { + IntPtr pfnProc = UnsafeNativeMethods.GetProcAddress(this, lpProcName); + if (pfnProc == IntPtr.Zero) + { + if (throwIfNotFound) + { + UnsafeNativeMethods.ThrowExceptionForLastWin32Error(); + } + else + { + return null; + } + } + + return Marshal.GetDelegateForFunctionPointer<TDelegate>(pfnProc); + } + + /// <summary> + /// Opens a library. If 'filename' is not a fully-qualified path, the default search path is used. + /// </summary> + public static SafeLibraryHandle Open(string filename) + { + const uint LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800U; // from libloaderapi.h + + SafeLibraryHandle handle = UnsafeNativeMethods.LoadLibraryEx(filename, IntPtr.Zero, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (handle == null || handle.IsInvalid) + { + UnsafeNativeMethods.ThrowExceptionForLastWin32Error(); + } + return handle; + } + + // Do not provide a finalizer - SafeHandle's critical finalizer will call ReleaseHandle for you. + protected override bool ReleaseHandle() + { + return UnsafeNativeMethods.FreeLibrary(handle); + } + + [SuppressUnmanagedCodeSecurity] + private static class UnsafeNativeMethods + { + // http://msdn.microsoft.com/en-us/library/ms683152(v=vs.85).aspx + [return: MarshalAs(UnmanagedType.Bool)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode)] + internal static extern bool FreeLibrary(IntPtr hModule); + + // http://msdn.microsoft.com/en-us/library/ms683212(v=vs.85).aspx + [DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true)] + internal static extern IntPtr GetProcAddress( + [In] SafeLibraryHandle hModule, + [In, MarshalAs(UnmanagedType.LPStr)] string lpProcName); + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx + [DllImport("kernel32.dll", EntryPoint = "LoadLibraryExW", CallingConvention = CallingConvention.Winapi, SetLastError = true)] + internal static extern SafeLibraryHandle LoadLibraryEx( + [In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName, + [In] IntPtr hFile, + [In] uint dwFlags); + + internal static void ThrowExceptionForLastWin32Error() + { + int hr = Marshal.GetHRForLastWin32Error(); + Marshal.ThrowExceptionForHR(hr); + } + } + } +} diff --git a/src/Servers/HttpSys/src/NativeInterop/UrlGroup.cs b/src/Servers/HttpSys/src/NativeInterop/UrlGroup.cs index 8f33c7b678..f1df0fce85 100644 --- a/src/Servers/HttpSys/src/NativeInterop/UrlGroup.cs +++ b/src/Servers/HttpSys/src/NativeInterop/UrlGroup.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } internal void SetProperty(HttpApiTypes.HTTP_SERVER_PROPERTY property, IntPtr info, uint infosize, bool throwOnError = true) - { + { Debug.Assert(info != IntPtr.Zero, "SetUrlGroupProperty called with invalid pointer"); CheckDisposed(); @@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { var exception = new HttpSysException((int)statusCode); - LogHelper.LogException(_logger, "SetUrlGroupProperty", exception); + _logger.LogError(0, exception, "SetUrlGroupProperty"); if (throwOnError) { throw exception; @@ -71,9 +71,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys internal void RegisterPrefix(string uriPrefix, int contextId) { - LogHelper.LogInfo(_logger, "Listening on prefix: " + uriPrefix); + _logger.LogDebug("Listening on prefix: " + uriPrefix); CheckDisposed(); - var statusCode = HttpApi.HttpAddUrlToUrlGroup(Id, uriPrefix, (ulong)contextId, 0); if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) @@ -88,10 +87,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } } - + internal bool UnregisterPrefix(string uriPrefix) { - LogHelper.LogInfo(_logger, "Stop listening on prefix: " + uriPrefix); + _logger.LogInformation("Stop listening on prefix: " + uriPrefix); CheckDisposed(); var statusCode = HttpApi.HttpRemoveUrlFromUrlGroup(Id, uriPrefix, 0); @@ -118,7 +117,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { - LogHelper.LogError(_logger, "CleanupV2Config", "Result: " + statusCode); + _logger.LogError("CleanupV2Config; Result: " + statusCode); } Id = 0; } diff --git a/src/Servers/HttpSys/src/RequestProcessing/ClientCertLoader.cs b/src/Servers/HttpSys/src/RequestProcessing/ClientCertLoader.cs index 74d7ed902f..ba40dd1be5 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/ClientCertLoader.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/ClientCertLoader.cs @@ -400,13 +400,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys } else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_INVALID_PARAMETER) { - LogHelper.LogError(logger, "GetChannelBindingFromTls", "Channel binding is not supported."); + logger.LogError("GetChannelBindingFromTls; Channel binding is not supported."); return null; // old schannel library which doesn't support CBT } else { // It's up to the consumer to fail if the missing ChannelBinding matters to them. - LogHelper.LogException(logger, "GetChannelBindingFromTls", new HttpSysException((int)statusCode)); + logger.LogError(0, new HttpSysException((int)statusCode), "GetChannelBindingFromTls"); break; } } diff --git a/src/Servers/HttpSys/src/RequestProcessing/Request.cs b/src/Servers/HttpSys/src/RequestProcessing/Request.cs index 049789abea..c30ae9bf07 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/Request.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/Request.cs @@ -293,7 +293,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys Protocol = handshake.Protocol; // The OS considers client and server TLS as different enum values. SslProtocols choose to combine those for some reason. // We need to fill in the client bits so the enum shows the expected protocol. - // https://docs.microsoft.com/en-us/windows/desktop/api/schannel/ns-schannel-_secpkgcontext_connectioninfo + // https://docs.microsoft.com/windows/desktop/api/schannel/ns-schannel-_secpkgcontext_connectioninfo // Compare to https://referencesource.microsoft.com/#System/net/System/Net/SecureProtocols/_SslState.cs,8905d1bf17729de3 #pragma warning disable CS0618 // Type or member is obsolete if ((Protocol & SslProtocols.Ssl2) != 0) diff --git a/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs b/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs index 89405cf538..eaa4bc23eb 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/RequestContext.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Security.Authentication.ExtendedProtection; using System.Security.Claims; using System.Security.Principal; @@ -119,14 +120,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (!Request.IsHttps) { - LogHelper.LogDebug(Logger, "TryGetChannelBinding", "Channel binding requires HTTPS."); + Logger.LogDebug("TryGetChannelBinding; Channel binding requires HTTPS."); return false; } value = ClientCertLoader.GetChannelBindingFromTls(Server.RequestQueue, Request.UConnectionId, Logger); Debug.Assert(value != null, "GetChannelBindingFromTls returned null even though OS supposedly supports Extended Protection"); - LogHelper.LogInfo(Logger, "Channel binding retrieved."); + Logger.LogInformation("Channel binding retrieved."); return value != null; } @@ -176,7 +177,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception ex) { - LogHelper.LogDebug(Logger, "Abort", ex); + Logger.LogDebug(0, ex, "Abort"); } _requestAbortSource.Dispose(); } @@ -218,5 +219,25 @@ namespace Microsoft.AspNetCore.Server.HttpSys // RequestQueueHandle may have been closed } } + + // You must still call ForceCancelRequest after this. + internal unsafe void SetResetCode(int errorCode) + { + if (!HttpApi.SupportsReset) + { + return; + } + + try + { + var streamError = new HttpApiTypes.HTTP_REQUEST_PROPERTY_STREAM_ERROR() { ErrorCode = (uint)errorCode }; + var statusCode = HttpApi.HttpSetRequestProperty(Server.RequestQueue.Handle, Request.RequestId, HttpApiTypes.HTTP_REQUEST_PROPERTY.HttpRequestPropertyStreamError, (void*)&streamError, + (uint)sizeof(HttpApiTypes.HTTP_REQUEST_PROPERTY_STREAM_ERROR), IntPtr.Zero); + } + catch (ObjectDisposedException) + { + // RequestQueueHandle may have been closed + } + } } } diff --git a/src/Servers/HttpSys/src/RequestProcessing/RequestStream.cs b/src/Servers/HttpSys/src/RequestProcessing/RequestStream.cs index f0bf45d68f..7d2202b809 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/RequestStream.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/RequestStream.cs @@ -165,7 +165,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF) { Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); - LogHelper.LogException(Logger, "Read", exception); + Logger.LogError(0, exception, "Read"); Abort(); throw exception; } @@ -242,7 +242,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception e) { - LogHelper.LogException(Logger, "BeginRead", e); + Logger.LogError(0, e, "BeginRead"); asyncResult.Dispose(); throw; } @@ -258,7 +258,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys else { Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); - LogHelper.LogException(Logger, "BeginRead", exception); + Logger.LogError(0, exception, "BeginRead"); Abort(); throw exception; } @@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys { asyncResult.Dispose(); Abort(); - LogHelper.LogException(Logger, "ReadAsync", e); + Logger.LogError(0, e, "ReadAsync"); throw; } @@ -386,7 +386,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys else { Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); - LogHelper.LogException(Logger, "ReadAsync", exception); + Logger.LogError(0, exception, "ReadAsync"); Abort(); throw exception; } diff --git a/src/Servers/HttpSys/src/RequestProcessing/Response.cs b/src/Servers/HttpSys/src/RequestProcessing/Response.cs index 5f29763d2f..3f8dd86f7e 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/Response.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/Response.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Net; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -28,6 +29,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys private long _expectedBodyLength; private BoundaryType _boundaryType; private HttpApiTypes.HTTP_RESPONSE_V2 _nativeResponse; + private HeaderCollection _trailers; internal Response(RequestContext requestContext) { @@ -142,6 +144,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys public HeaderCollection Headers { get; } + public HeaderCollection Trailers => _trailers ??= new HeaderCollection(checkTrailers: true) { IsReadOnly = BodyIsFinished }; + + internal bool HasTrailers => _trailers?.Count > 0; + + // Trailers are supported on this OS, it's HTTP/2, and the app added a Trailer response header to announce trailers were intended. + // Needed to delay the completion of Content-Length responses. + internal bool TrailersExpected => HasTrailers + || (HttpApi.SupportsTrailers && Request.ProtocolVersion >= HttpVersion.Version20 + && Headers.ContainsKey(HttpKnownHeaderNames.Trailer)); + internal long ExpectedBodyLength { get { return _expectedBodyLength; } @@ -168,6 +180,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + // The response is being finished with or without trailers. Mark them as readonly to inform + // callers if they try to add them too late. E.g. after Content-Length or CompleteAsync(). + internal void MakeTrailersReadOnly() + { + if (_trailers != null) + { + _trailers.IsReadOnly = true; + } + } + internal void Abort() { // Update state for HasStarted. Do not attempt a graceful Dispose. @@ -400,7 +422,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys _boundaryType = BoundaryType.ContentLength; // ComputeLeftToWrite checks for HEAD requests when setting _leftToWrite _expectedBodyLength = responseContentLength.Value; - if (_expectedBodyLength == writeCount && !isHeadRequest) + if (_expectedBodyLength == writeCount && !isHeadRequest && !TrailersExpected) { // A single write with the whole content-length. Http.Sys will set the content-length for us in this scenario. // If we don't remove it then range requests served from cache will have two. @@ -430,6 +452,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys else { // v1.0 and the length cannot be determined, so we must close the connection after writing data + // Or v2.0 and chunking isn't required. keepConnectionAlive = false; _boundaryType = BoundaryType.Close; } @@ -622,6 +645,73 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + internal unsafe void SerializeTrailers(HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks, int currentChunk, List<GCHandle> pins) + { + Debug.Assert(currentChunk == dataChunks.Length - 1); + Debug.Assert(HasTrailers); + MakeTrailersReadOnly(); + var trailerCount = 0; + + foreach (var trailerPair in Trailers) + { + trailerCount += trailerPair.Value.Count; + } + + var pinnedHeaders = new List<GCHandle>(); + + var unknownHeaders = new HttpApiTypes.HTTP_UNKNOWN_HEADER[trailerCount]; + var gcHandle = GCHandle.Alloc(unknownHeaders, GCHandleType.Pinned); + pinnedHeaders.Add(gcHandle); + dataChunks[currentChunk].DataChunkType = HttpApiTypes.HTTP_DATA_CHUNK_TYPE.HttpDataChunkTrailers; + dataChunks[currentChunk].trailers.trailerCount = (ushort)trailerCount; + dataChunks[currentChunk].trailers.pTrailers = gcHandle.AddrOfPinnedObject(); + + try + { + var unknownHeadersOffset = 0; + + foreach (var headerPair in Trailers) + { + if (headerPair.Value.Count == 0) + { + continue; + } + + var headerName = headerPair.Key; + var headerValues = headerPair.Value; + + for (int headerValueIndex = 0; headerValueIndex < headerValues.Count; headerValueIndex++) + { + // Add Name + var bytes = HeaderEncoding.GetBytes(headerName); + unknownHeaders[unknownHeadersOffset].NameLength = (ushort)bytes.Length; + gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); + pinnedHeaders.Add(gcHandle); + unknownHeaders[unknownHeadersOffset].pName = (byte*)gcHandle.AddrOfPinnedObject(); + + // Add Value + var headerValue = headerValues[headerValueIndex] ?? string.Empty; + bytes = HeaderEncoding.GetBytes(headerValue); + unknownHeaders[unknownHeadersOffset].RawValueLength = (ushort)bytes.Length; + gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); + pinnedHeaders.Add(gcHandle); + unknownHeaders[unknownHeadersOffset].pRawValue = (byte*)gcHandle.AddrOfPinnedObject(); + unknownHeadersOffset++; + } + } + + Debug.Assert(unknownHeadersOffset == trailerCount); + } + catch + { + FreePinnedHeaders(pinnedHeaders); + throw; + } + + // Success, keep the pins. + pins.AddRange(pinnedHeaders); + } + // Subset of ComputeHeaders internal void SendOpaqueUpgrade() { diff --git a/src/Servers/HttpSys/src/RequestProcessing/ResponseBody.cs b/src/Servers/HttpSys/src/RequestProcessing/ResponseBody.cs index 8f6341db63..ec39ff2f73 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/ResponseBody.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/ResponseBody.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Net; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -126,9 +127,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys var flags = ComputeLeftToWrite(data.Count, endOfRequest); if (endOfRequest && _leftToWrite > 0) { + if (!RequestContext.DisconnectToken.IsCancellationRequested) + { + // This is logged rather than thrown because it is too late for an exception to be visible in user code. + Logger.LogError("ResponseStream::Dispose; Fewer bytes were written than were specified in the Content-Length."); + } _requestContext.Abort(); - // This is logged rather than thrown because it is too late for an exception to be visible in user code. - LogHelper.LogError(Logger, "ResponseStream::Dispose", "Fewer bytes were written than were specified in the Content-Length."); return; } @@ -171,14 +175,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys if (ThrowWriteExceptions) { var exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); - LogHelper.LogException(Logger, "Flush", exception); + Logger.LogError(0, exception, "Flush"); Abort(); throw exception; } else { // Abort the request but do not close the stream, let future writes complete silently - LogHelper.LogDebug(Logger, "Flush", $"Ignored write exception: {statusCode}"); + Logger.LogDebug($"Flush; Ignored write exception: {statusCode}"); Abort(dispose: false); } } @@ -187,26 +191,34 @@ namespace Microsoft.AspNetCore.Server.HttpSys private List<GCHandle> PinDataBuffers(bool endOfRequest, ArraySegment<byte> data, out HttpApiTypes.HTTP_DATA_CHUNK[] dataChunks) { var pins = new List<GCHandle>(); + var hasData = data.Count > 0; var chunked = _requestContext.Response.BoundaryType == BoundaryType.Chunked; + var addTrailers = endOfRequest && _requestContext.Response.HasTrailers; + Debug.Assert(!(addTrailers && chunked), "Trailers aren't currently supported for HTTP/1.1 chunking."); var currentChunk = 0; // Figure out how many data chunks - if (chunked && data.Count == 0 && endOfRequest) + if (chunked && !hasData && endOfRequest) { dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[1]; SetDataChunk(dataChunks, ref currentChunk, pins, new ArraySegment<byte>(Helpers.ChunkTerminator)); return pins; } - else if (data.Count == 0) + else if (!hasData && !addTrailers) { // No data dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[0]; return pins; } - var chunkCount = 1; - if (chunked) + var chunkCount = hasData ? 1 : 0; + if (addTrailers) { + chunkCount++; + } + else if (chunked) // HTTP/1.1 chunking, not currently supported with trailers + { + Debug.Assert(hasData); // Chunk framing chunkCount += 2; @@ -216,6 +228,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys chunkCount += 1; } } + dataChunks = new HttpApiTypes.HTTP_DATA_CHUNK[chunkCount]; if (chunked) @@ -224,7 +237,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys SetDataChunk(dataChunks, ref currentChunk, pins, chunkHeaderBuffer); } - SetDataChunk(dataChunks, ref currentChunk, pins, data); + if (hasData) + { + SetDataChunk(dataChunks, ref currentChunk, pins, data); + } if (chunked) { @@ -236,6 +252,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + if (addTrailers) + { + _requestContext.Response.SerializeTrailers(dataChunks, currentChunk, pins); + } + else if (endOfRequest) + { + _requestContext.Response.MakeTrailersReadOnly(); + } + return pins; } @@ -320,7 +345,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception e) { - LogHelper.LogException(Logger, "FlushAsync", e); + Logger.LogError(0, e, "FlushAsync"); asyncResult.Dispose(); Abort(); throw; @@ -330,21 +355,21 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (cancellationToken.IsCancellationRequested) { - LogHelper.LogDebug(Logger, "FlushAsync", $"Write cancelled with error code: {statusCode}"); + Logger.LogDebug($"FlushAsync; Write cancelled with error code: {statusCode}"); asyncResult.Cancel(ThrowWriteExceptions); } else if (ThrowWriteExceptions) { asyncResult.Dispose(); Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); - LogHelper.LogException(Logger, "FlushAsync", exception); + Logger.LogError(0, exception, "FlushAsync"); Abort(); throw exception; } else { // Abort the request but do not close the stream, let future writes complete silently - LogHelper.LogDebug(Logger, "FlushAsync", $"Ignored write exception: {statusCode}"); + Logger.LogDebug($"FlushAsync; Ignored write exception: {statusCode}"); asyncResult.FailSilently(); } } @@ -433,7 +458,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys { flags |= HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT; } - else if (!endOfRequest && _leftToWrite != writeCount) + else if (!endOfRequest + && (_leftToWrite != writeCount || _requestContext.Response.TrailersExpected)) { flags |= HttpApiTypes.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA; } @@ -444,9 +470,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys // keep track of the data transferred _leftToWrite -= writeCount; } - if (_leftToWrite == 0) + if (_leftToWrite == 0 && !_requestContext.Response.TrailersExpected) { // in this case we already passed 0 as the flag, so we don't need to call HttpSendResponseEntityBody() when we Close() + _requestContext.Response.MakeTrailersReadOnly(); _disposed = true; } // else -1 unlimited @@ -612,7 +639,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception e) { - LogHelper.LogException(Logger, "SendFileAsync", e); + Logger.LogError(0, e, "SendFileAsync"); asyncResult.Dispose(); Abort(); throw; @@ -622,21 +649,21 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (cancellationToken.IsCancellationRequested) { - LogHelper.LogDebug(Logger, "SendFileAsync", $"Write cancelled with error code: {statusCode}"); + Logger.LogDebug($"SendFileAsync; Write cancelled with error code: {statusCode}"); asyncResult.Cancel(ThrowWriteExceptions); } else if (ThrowWriteExceptions) { asyncResult.Dispose(); var exception = new IOException(string.Empty, new HttpSysException((int)statusCode)); - LogHelper.LogException(Logger, "SendFileAsync", exception); + Logger.LogError(0, exception, "SendFileAsync"); Abort(); throw exception; } else { // Abort the request but do not close the stream, let future writes complete silently - LogHelper.LogDebug(Logger, "SendFileAsync", $"Ignored write exception: {statusCode}"); + Logger.LogDebug($"SendFileAsync; Ignored write exception: {statusCode}"); asyncResult.FailSilently(); } } @@ -666,8 +693,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys { return; } - _disposed = true; FlushInternal(endOfRequest: true); + _disposed = true; } } finally diff --git a/src/Servers/HttpSys/src/RequestProcessing/ResponseStreamAsyncResult.cs b/src/Servers/HttpSys/src/RequestProcessing/ResponseStreamAsyncResult.cs index 32a90e4b51..e2611cd897 100644 --- a/src/Servers/HttpSys/src/RequestProcessing/ResponseStreamAsyncResult.cs +++ b/src/Servers/HttpSys/src/RequestProcessing/ResponseStreamAsyncResult.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.HttpSys.Internal; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Server.HttpSys { @@ -232,18 +233,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys { if (asyncResult._cancellationToken.IsCancellationRequested) { - LogHelper.LogDebug(logger, "FlushAsync.IOCompleted", $"Write cancelled with error code: {errorCode}"); + logger.LogDebug($"FlushAsync.IOCompleted; Write cancelled with error code: {errorCode}"); asyncResult.Cancel(asyncResult._responseStream.ThrowWriteExceptions); } else if (asyncResult._responseStream.ThrowWriteExceptions) { var exception = new IOException(string.Empty, new HttpSysException((int)errorCode)); - LogHelper.LogException(logger, "FlushAsync.IOCompleted", exception); + logger.LogError(0, exception, "FlushAsync.IOCompleted"); asyncResult.Fail(exception); } else { - LogHelper.LogDebug(logger, "FlushAsync.IOCompleted", $"Ignored write exception: {errorCode}"); + logger.LogDebug($"FlushAsync.IOCompleted; Ignored write exception: {errorCode}"); asyncResult.FailSilently(); } } @@ -258,7 +259,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys // TODO: Verbose log // for (int i = 0; i < asyncResult._dataChunks.Length; i++) // { - // Logging.Dump(Logging.HttpListener, asyncResult, "Callback", (IntPtr)asyncResult._dataChunks[0].fromMemory.pBuffer, (int)asyncResult._dataChunks[0].fromMemory.BufferLength); + // Logging.Dump(Logging.HttpListener, asyncResult, "Callback", (IntPtr)asyncResult._dataChunks[0].fromMemory.pBuffer, (int)asyncResult._dataChunks[0].fromMemory.BufferLength); // } } asyncResult.Complete(); @@ -266,7 +267,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } catch (Exception e) { - LogHelper.LogException(logger, "FlushAsync.IOCompleted", e); + logger.LogError(0, e, "FlushAsync.IOCompleted"); asyncResult.Fail(e); } } diff --git a/src/Servers/HttpSys/src/StandardFeatureCollection.cs b/src/Servers/HttpSys/src/StandardFeatureCollection.cs index e63155c823..304b39b070 100644 --- a/src/Servers/HttpSys/src/StandardFeatureCollection.cs +++ b/src/Servers/HttpSys/src/StandardFeatureCollection.cs @@ -27,6 +27,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys { typeof(IHttpMaxRequestBodySizeFeature), _identityFunc }, { typeof(IHttpBodyControlFeature), _identityFunc }, { typeof(IHttpSysRequestInfoFeature), _identityFunc }, + { typeof(IHttpResponseTrailersFeature), ctx => ctx.GetResponseTrailersFeature() }, + { typeof(IHttpResetFeature), ctx => ctx.GetResetFeature() }, }; private readonly FeatureContext _featureContext; diff --git a/src/Servers/HttpSys/src/UrlPrefixCollection.cs b/src/Servers/HttpSys/src/UrlPrefixCollection.cs index e38dd9a5d2..ac92c6591d 100644 --- a/src/Servers/HttpSys/src/UrlPrefixCollection.cs +++ b/src/Servers/HttpSys/src/UrlPrefixCollection.cs @@ -4,7 +4,10 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.HttpSys.Internal; namespace Microsoft.AspNetCore.Server.HttpSys { @@ -17,6 +20,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys private UrlGroup _urlGroup; private int _nextId = 1; + // Valid port range of 5000 - 48000. + private const int BasePort = 5000; + private const int MaxPortIndex = 43000; + private const int MaxRetries = 1000; + private static int NextPortIndex; + internal UrlPrefixCollection() { } @@ -166,10 +175,55 @@ namespace Microsoft.AspNetCore.Server.HttpSys { _urlGroup = urlGroup; // go through the uri list and register for each one of them - foreach (var pair in _prefixes) + // Call ToList to avoid modification when enumerating. + foreach (var pair in _prefixes.ToList()) { - // We'll get this index back on each request and use it to look up the prefix to calculate PathBase. - _urlGroup.RegisterPrefix(pair.Value.FullPrefix, pair.Key); + var urlPrefix = pair.Value; + if (urlPrefix.PortValue == 0) + { + if (urlPrefix.IsHttps) + { + throw new InvalidOperationException("Cannot bind to port 0 with https."); + } + + FindHttpPortUnsynchronized(pair.Key, urlPrefix); + } + else + { + // We'll get this index back on each request and use it to look up the prefix to calculate PathBase. + _urlGroup.RegisterPrefix(pair.Value.FullPrefix, pair.Key); + } + } + } + } + + private void FindHttpPortUnsynchronized(int key, UrlPrefix urlPrefix) + { + for (var index = 0; index < MaxRetries; index++) + { + try + { + // Bit of complicated math to always try 3000 ports, starting from NextPortIndex + 5000, + // circling back around if we go above 8000 back to 5000, and so on. + var port = ((index + NextPortIndex) % MaxPortIndex) + BasePort; + + Debug.Assert(port >= 5000 || port < 8000); + + var newPrefix = UrlPrefix.Create(urlPrefix.Scheme, urlPrefix.Host, port, urlPrefix.Path); + _urlGroup.RegisterPrefix(newPrefix.FullPrefix, key); + _prefixes[key] = newPrefix; + + NextPortIndex += index + 1; + return; + } + catch (HttpSysException ex) + { + if ((ex.ErrorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_ACCESS_DENIED + && ex.ErrorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SHARING_VIOLATION + && ex.ErrorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_ALREADY_EXISTS) || index == MaxRetries - 1) + { + throw; + } } } } diff --git a/src/Servers/HttpSys/src/WebHostBuilderHttpSysExtensions.cs b/src/Servers/HttpSys/src/WebHostBuilderHttpSysExtensions.cs index 7b4caaef62..f7c2b9445f 100644 --- a/src/Servers/HttpSys/src/WebHostBuilderHttpSysExtensions.cs +++ b/src/Servers/HttpSys/src/WebHostBuilderHttpSysExtensions.cs @@ -9,16 +9,19 @@ using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Hosting { + /// <summary> + /// Provides extensions method to use Http.sys as the server for the web host. + /// </summary> public static class WebHostBuilderHttpSysExtensions { /// <summary> - /// Specify HttpSys as the server to be used by the web host. + /// Specify Http.sys as the server to be used by the web host. /// </summary> /// <param name="hostBuilder"> /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure. /// </param> /// <returns> - /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder. + /// A reference to the <see cref="IWebHostBuilder" /> parameter object. /// </returns> public static IWebHostBuilder UseHttpSys(this IWebHostBuilder hostBuilder) { @@ -38,16 +41,16 @@ namespace Microsoft.AspNetCore.Hosting } /// <summary> - /// Specify HttpSys as the server to be used by the web host. + /// Specify Http.sys as the server to be used by the web host. /// </summary> /// <param name="hostBuilder"> /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure. /// </param> /// <param name="options"> - /// A callback to configure HttpSys options. + /// A callback to configure Http.sys options. /// </param> /// <returns> - /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder. + /// A reference to the <see cref="IWebHostBuilder" /> parameter object. /// </returns> public static IWebHostBuilder UseHttpSys(this IWebHostBuilder hostBuilder, Action<HttpSysOptions> options) { diff --git a/src/Servers/HttpSys/startvs.cmd b/src/Servers/HttpSys/startvs.cmd new file mode 100644 index 0000000000..94b00042d2 --- /dev/null +++ b/src/Servers/HttpSys/startvs.cmd @@ -0,0 +1,3 @@ +@ECHO OFF + +%~dp0..\..\..\startvs.cmd %~dp0HttpSysServer.sln diff --git a/src/Servers/HttpSys/test/FunctionalTests/AuthenticationTests.cs b/src/Servers/HttpSys/test/FunctionalTests/AuthenticationTests.cs index be66db9655..2886b2d8d1 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/AuthenticationTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/AuthenticationTests.cs @@ -368,6 +368,38 @@ namespace Microsoft.AspNetCore.Server.HttpSys } } + [ConditionalTheory] + [InlineData(AuthenticationSchemes.Negotiate)] + [InlineData(AuthenticationSchemes.NTLM)] + // [InlineData(AuthenticationSchemes.Digest)] // TODO: Not implemented + // [InlineData(AuthenticationSchemes.Basic)] // Doesn't work with default creds + [InlineData(AuthenticationSchemes.Negotiate | AuthenticationSchemes.NTLM | /* AuthenticationSchemes.Digest |*/ AuthenticationSchemes.Basic)] + public async Task AuthTypes_DisableAutomaticAuthentication(AuthenticationSchemes authType) + { + using (var server = Utilities.CreateDynamicHost(out var address, options => + { + options.Authentication.AutomaticAuthentication = false; + options.Authentication.Schemes = authType; + options.Authentication.AllowAnonymous = DenyAnoymous; + }, + async httpContext => + { + Assert.NotNull(httpContext.User); + Assert.NotNull(httpContext.User.Identity); + Assert.False(httpContext.User.Identity.IsAuthenticated); + + var authenticateResult = await httpContext.AuthenticateAsync(HttpSysDefaults.AuthenticationScheme); + + Assert.NotNull(authenticateResult.Principal); + Assert.NotNull(authenticateResult.Principal.Identity); + Assert.True(authenticateResult.Principal.Identity.IsAuthenticated); + })) + { + var response = await SendRequestAsync(address, useDefaultCredentials: true); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + } + private async Task<HttpResponseMessage> SendRequestAsync(string uri, bool useDefaultCredentials = false) { HttpClientHandler handler = new HttpClientHandler(); diff --git a/src/Servers/HttpSys/test/FunctionalTests/Http2Tests.cs b/src/Servers/HttpSys/test/FunctionalTests/Http2Tests.cs new file mode 100644 index 0000000000..57e5722557 --- /dev/null +++ b/src/Servers/HttpSys/test/FunctionalTests/Http2Tests.cs @@ -0,0 +1,661 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Http2Cat; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +using Microsoft.AspNetCore.Testing; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; +using Xunit; + +namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests +{ + public class Http2Tests + { + [ConditionalFact(Skip = "https://github.com/dotnet/aspnetcore/issues/17420")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H1, SkipReason = "This is last version without GoAway support")] + public async Task ConnectionClose_NoOSSupport_NoGoAway() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.Headers[HeaderNames.Connection] = "close"; + return Task.FromResult(0); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + await h2Connection.ReceiveHeadersAsync(1, endStream: true, decodedHeaders => + { + // HTTP/2 filters out the connection header + Assert.False(decodedHeaders.ContainsKey(HeaderNames.Connection)); + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + // Send and receive a second request to ensure there is no GoAway frame on the wire yet. + + await h2Connection.StartStreamAsync(3, Http2Utilities.BrowserRequestHeaders, endStream: true); + + await h2Connection.ReceiveHeadersAsync(3, endStream: true, decodedHeaders => + { + // HTTP/2 filters out the connection header + Assert.False(decodedHeaders.ContainsKey(HeaderNames.Connection)); + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + await h2Connection.StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H2, SkipReason = "GoAway support was added in Win10_19H2.")] + public async Task ConnectionClose_OSSupport_SendsGoAway() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.Headers[HeaderNames.Connection] = "close"; + return Task.FromResult(0); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + var goAwayFrame = await h2Connection.ReceiveFrameAsync(); + h2Connection.VerifyGoAway(goAwayFrame, int.MaxValue, Http2ErrorCode.NO_ERROR); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + // HTTP/2 filters out the connection header + Assert.False(decodedHeaders.ContainsKey(HeaderNames.Connection)); + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: true, length: 0); + + // Http.Sys doesn't send a final GoAway unless we ignore the first one and send 200 additional streams. + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_19H2, SkipReason = "GoAway support was added in Win10_19H2.")] + public async Task ConnectionClose_AdditionalRequests_ReceivesSecondGoAway() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.Headers[HeaderNames.Connection] = "close"; + return Task.FromResult(0); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + var streamId = 1; + await h2Connection.StartStreamAsync(streamId, Http2Utilities.BrowserRequestHeaders, endStream: true); + + var goAwayFrame = await h2Connection.ReceiveFrameAsync(); + h2Connection.VerifyGoAway(goAwayFrame, int.MaxValue, Http2ErrorCode.NO_ERROR); + + await h2Connection.ReceiveHeadersAsync(streamId, decodedHeaders => + { + // HTTP/2 filters out the connection header + Assert.False(decodedHeaders.ContainsKey(HeaderNames.Connection)); + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, streamId, endOfStream: true, length: 0); + + // Http.Sys doesn't send a final GoAway unless we ignore the first one and send 200 additional streams. + + for (var i = 1; i < 200; i++) + { + streamId = 1 + (i * 2); // Odds. + await h2Connection.StartStreamAsync(streamId, Http2Utilities.BrowserRequestHeaders, endStream: true); + + await h2Connection.ReceiveHeadersAsync(streamId, decodedHeaders => + { + // HTTP/2 filters out the connection header + Assert.False(decodedHeaders.ContainsKey(HeaderNames.Connection)); + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, streamId, endOfStream: true, length: 0); + } + + streamId = 1 + (200 * 2); // Odds. + await h2Connection.StartStreamAsync(streamId, Http2Utilities.BrowserRequestHeaders, endStream: true); + + // Final GoAway + goAwayFrame = await h2Connection.ReceiveFrameAsync(); + h2Connection.VerifyGoAway(goAwayFrame, streamId, Http2ErrorCode.NO_ERROR); + + // Normal response + await h2Connection.ReceiveHeadersAsync(streamId, decodedHeaders => + { + // HTTP/2 filters out the connection header + Assert.False(decodedHeaders.ContainsKey(HeaderNames.Connection)); + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, streamId, endOfStream: true, length: 0); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")] + public async Task AppException_BeforeHeaders_500() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + throw new Exception("Application exception"); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("500", decodedHeaders[HeaderNames.Status]); + }); + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: true, length: 0); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "This is last version without custom Reset support")] + public async Task AppException_AfterHeaders_PriorOSVersions_ResetCancel() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + await httpContext.Response.Body.FlushAsync(); + throw new Exception("Application exception"); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, Http2ErrorCode.CANCEL); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Custom Reset support was added in Win10_20H2.")] + public async Task AppException_AfterHeaders_ResetInternalError() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + await httpContext.Response.Body.FlushAsync(); + throw new Exception("Application exception"); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, Http2ErrorCode.INTERNAL_ERROR); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + public async Task Reset_Http1_NotSupported() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + Assert.Equal("HTTP/1.1", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.Null(feature); + return httpContext.Response.WriteAsync("Hello World"); + }); + + var handler = new HttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; + using HttpClient client = new HttpClient(handler); + client.DefaultRequestVersion = HttpVersion.Version11; + var response = await client.GetStringAsync(address); + Assert.Equal("Hello World", response); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10, SkipReason = "Http2 requires Win10")] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "This is last version without Reset support")] + public async Task Reset_PriorOSVersions_NotSupported() + { + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.Null(feature); + return httpContext.Response.WriteAsync("Hello World"); + }); + + var handler = new HttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; + using HttpClient client = new HttpClient(handler); + client.DefaultRequestVersion = HttpVersion.Version20; + var response = await client.GetStringAsync(address); + Assert.Equal("Hello World", response); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_BeforeResponse_Resets() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + feature.Reset(1111); // Custom + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + return Task.FromResult(0); + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_AfterResponseHeaders_Resets() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + await httpContext.Response.Body.FlushAsync(); + feature.Reset(1111); // Custom + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_DurringResponseBody_Resets() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + await httpContext.Response.WriteAsync("Hello World"); + feature.Reset(1111); // Custom + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: false, length: 11); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_AfterCompleteAsync_NoReset() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + await httpContext.Response.WriteAsync("Hello World"); + await httpContext.Response.CompleteAsync(); + // The request and response are fully complete, the reset doesn't get sent. + feature.Reset(1111); + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: false, length: 11); + + dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: true, length: 0); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_BeforeRequestBody_Resets() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + var readTask = httpContext.Request.Body.ReadAsync(new byte[10], 0, 10); + + feature.Reset(1111); + + await Assert.ThrowsAsync<IOException>(() => readTask); + + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.PostRequestHeaders, endStream: false); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_DurringRequestBody_Resets() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + + var read = await httpContext.Request.Body.ReadAsync(new byte[10], 0, 10); + Assert.Equal(10, read); + + var readTask = httpContext.Request.Body.ReadAsync(new byte[10], 0, 10); + feature.Reset(1111); + await Assert.ThrowsAsync<IOException>(() => readTask); + + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.PostRequestHeaders, endStream: false); + await h2Connection.SendDataAsync(1, new byte[10], endStream: false); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: (Http2ErrorCode)1111); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Reset support was added in Win10_20H2.")] + public async Task Reset_CompleteAsyncDurringRequestBody_Resets() + { + var appResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using var server = Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + try + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + var feature = httpContext.Features.Get<IHttpResetFeature>(); + Assert.NotNull(feature); + + var read = await httpContext.Request.Body.ReadAsync(new byte[10], 0, 10); + Assert.Equal(10, read); + + var readTask = httpContext.Request.Body.ReadAsync(new byte[10], 0, 10); + await httpContext.Response.CompleteAsync(); + feature.Reset((int)Http2ErrorCode.NO_ERROR); // GRPC does this + await Assert.ThrowsAsync<IOException>(() => readTask); + + appResult.SetResult(0); + } + catch (Exception ex) + { + appResult.SetException(ex); + } + }); + + await new HostBuilder() + .UseHttp2Cat(address, async h2Connection => + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.PostRequestHeaders, endStream: false); + await h2Connection.SendDataAsync(1, new byte[10], endStream: false); + + // Any app errors? + Assert.Equal(0, await appResult.Task.DefaultTimeout()); + + await h2Connection.ReceiveHeadersAsync(1, decodedHeaders => + { + Assert.Equal("200", decodedHeaders[HeaderNames.Status]); + }); + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyDataFrame(dataFrame, 1, endOfStream: true, length: 0); + + var resetFrame = await h2Connection.ReceiveFrameAsync(); + Http2Utilities.VerifyResetFrame(resetFrame, expectedStreamId: 1, expectedErrorCode: Http2ErrorCode.NO_ERROR); + + h2Connection.Logger.LogInformation("Connection stopped."); + }) + .Build().RunAsync(); + } + } +} diff --git a/src/Servers/HttpSys/test/FunctionalTests/HttpsTests.cs b/src/Servers/HttpSys/test/FunctionalTests/HttpsTests.cs index 6bbaeb13cb..43d6005bc1 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/HttpsTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/HttpsTests.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using System.Linq; using System.Net.Http; using System.Runtime.InteropServices; using System.Security.Authentication; @@ -20,12 +19,9 @@ using Xunit; namespace Microsoft.AspNetCore.Server.HttpSys { - // Flaky doesn't support classes :( - // https://github.com/aspnet/Extensions/issues/1568 public class HttpsTests { [ConditionalFact] - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2209", FlakyOn.Helix.All)] public async Task Https_200OK_Success() { using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => @@ -39,7 +35,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2209", FlakyOn.Helix.All)] public async Task Https_SendHelloWorld_Success() { using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => @@ -55,7 +50,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2209", FlakyOn.Helix.All)] public async Task Https_EchoHelloWorld_Success() { using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => @@ -73,7 +67,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2209", FlakyOn.Helix.All)] public async Task Https_ClientCertNotSent_ClientCertNotPresent() { using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => @@ -110,8 +103,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2209", FlakyOn.Helix.All)] - [OSDontSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] public async Task Https_SkipsITlsHandshakeFeatureOnWin7() { using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => @@ -133,8 +125,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2209", FlakyOn.Helix.All)] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task Https_SetsITlsHandshakeFeature() { using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => @@ -164,7 +155,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task Https_ITlsHandshakeFeature_MatchesIHttpSysExtensionInfoFeature() { using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => @@ -206,16 +197,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys private async Task<string> SendRequestAsync(string uri, X509Certificate cert = null) { - var handler = new WinHttpHandler(); - handler.ServerCertificateValidationCallback = (a, b, c, d) => true; + var handler = new HttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; if (cert != null) { handler.ClientCertificates.Add(cert); } - using (HttpClient client = new HttpClient(handler)) - { - return await client.GetStringAsync(uri); - } + using HttpClient client = new HttpClient(handler); + return await client.GetStringAsync(uri); } private async Task<string> SendRequestAsync(string uri, string upload) diff --git a/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs b/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs index 250ff9c9be..0e5270b82b 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/MessagePumpTests.cs @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys [InlineData("invalid address")] [InlineData("")] [InlineData(null)] - public void OverridingIServerAdressesFeatureWithDirectConfiguration_WarnsOnStart(string serverAddress) + public void OverridingIServerAddressesFeatureWithDirectConfiguration_WarnsOnStart(string serverAddress) { var overrideAddress = "http://localhost:11002/"; @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - public void UseIServerAdressesFeature_WhenNoDirectConfiguration() + public void UseIServerAddressesFeature_WhenNoDirectConfiguration() { var serverAddress = "http://localhost:11001/"; @@ -114,7 +114,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys { server.StartAsync(new DummyApplication(), CancellationToken.None).Wait(); - Assert.Equal(Constants.DefaultServerAddress, server.Features.Get<IServerAddressesFeature>().Addresses.Single()); + // Trailing slash is added when put in UrlPrefix. + Assert.StartsWith(Constants.DefaultServerAddress, server.Features.Get<IServerAddressesFeature>().Addresses.Single()); } } diff --git a/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj b/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj index 281d455f5e..16991ba87a 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj +++ b/src/Servers/HttpSys/test/FunctionalTests/Microsoft.AspNetCore.Server.HttpSys.FunctionalTests.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> @@ -6,8 +6,17 @@ <AllowUnsafeBlocks>true</AllowUnsafeBlocks> </PropertyGroup> + <ItemGroup> + <Compile Include="$(SharedSourceRoot)Http2\**\*.cs" LinkBase="Shared\Http2\" /> + <Compile Include="$(SharedSourceRoot)Http2cat\**\*.cs" LinkBase="Shared\Http2cat" /> + <Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" /> + <Compile Include="$(SharedSourceRoot)TaskToApm.cs" Link="Shared\TaskToApm.cs" /> + </ItemGroup> + <ItemGroup> <Reference Include="Microsoft.AspNetCore.Server.HttpSys" /> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" /> + <Reference Include="Microsoft.Extensions.Hosting" /> <Reference Include="System.Net.Http.WinHttpHandler" /> </ItemGroup> @@ -22,4 +31,15 @@ <HelixPreCommand Include="call RunPowershell.cmd UpdateIISExpressCertificate.ps1 || exit /b 1" /> </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx"> + <ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> + <EmbeddedResource Include="$(SharedSourceRoot)Http2\SR.resx" Link="Shared\Http2\SR.resx"> + <ManifestResourceName>System.Net.Http.SR</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> + </ItemGroup> + </Project> diff --git a/src/Servers/HttpSys/test/FunctionalTests/OSDontSkipConditionAttribute.cs b/src/Servers/HttpSys/test/FunctionalTests/OSDontSkipConditionAttribute.cs deleted file mode 100644 index ee257df989..0000000000 --- a/src/Servers/HttpSys/test/FunctionalTests/OSDontSkipConditionAttribute.cs +++ /dev/null @@ -1,99 +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. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; - -namespace Microsoft.AspNetCore.Testing -{ - // Skip except on a specific OS and version - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)] - public class OSDontSkipConditionAttribute : Attribute, ITestCondition - { - private readonly OperatingSystems _includedOperatingSystem; - private readonly IEnumerable<string> _includedVersions; - private readonly OperatingSystems _osPlatform; - private readonly string _osVersion; - - public OSDontSkipConditionAttribute(OperatingSystems operatingSystem, params string[] versions) : - this( - operatingSystem, - GetCurrentOS(), - GetCurrentOSVersion(), - versions) - { - } - - // to enable unit testing - internal OSDontSkipConditionAttribute( - OperatingSystems operatingSystem, OperatingSystems osPlatform, string osVersion, params string[] versions) - { - _includedOperatingSystem = operatingSystem; - _includedVersions = versions ?? Enumerable.Empty<string>(); - _osPlatform = osPlatform; - _osVersion = osVersion; - } - - public bool IsMet - { - get - { - var currentOSInfo = new OSInfo() - { - OperatingSystem = _osPlatform, - Version = _osVersion, - }; - - var skip = (_includedOperatingSystem & currentOSInfo.OperatingSystem) != currentOSInfo.OperatingSystem; - if (!skip && _includedVersions.Any()) - { - skip = !_includedVersions.Any(inc => _osVersion.StartsWith(inc, StringComparison.OrdinalIgnoreCase)); - } - - // Since a test would be excuted only if 'IsMet' is true, return false if we want to skip - return !skip; - } - } - - public string SkipReason { get; set; } = "Test cannot run on this operating system."; - - static private OperatingSystems GetCurrentOS() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return OperatingSystems.Windows; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return OperatingSystems.Linux; - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return OperatingSystems.MacOSX; - } - throw new PlatformNotSupportedException(); - } - - static private string GetCurrentOSVersion() - { - // currently not used on other OS's - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return Environment.OSVersion.Version.ToString(); - } - else - { - return string.Empty; - } - } - - private class OSInfo - { - public OperatingSystems OperatingSystem { get; set; } - - public string Version { get; set; } - } - } -} \ No newline at end of file diff --git a/src/Servers/HttpSys/test/FunctionalTests/OpaqueUpgradeTests.cs b/src/Servers/HttpSys/test/FunctionalTests/OpaqueUpgradeTests.cs index b722f3ab1f..a2c39a4c47 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/OpaqueUpgradeTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/OpaqueUpgradeTests.cs @@ -6,7 +6,6 @@ using System.IO; using System.Net.Http; using System.Net.Sockets; using System.Text; -using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; @@ -18,7 +17,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys public class OpaqueUpgradeTests { [ConditionalFact] - [OSDontSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] public async Task OpaqueUpgrade_DownLevel_FeatureIsAbsent() { using (Utilities.CreateHttpServer(out var address, httpContext => @@ -44,7 +43,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task OpaqueUpgrade_SupportKeys_Present() { string address; @@ -71,7 +70,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task OpaqueUpgrade_AfterHeadersSent_Throws() { bool? upgradeThrew = null; @@ -101,7 +100,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task OpaqueUpgrade_GetUpgrade_Success() { var upgraded = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously); @@ -123,7 +122,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task OpaqueUpgrade_GetUpgrade_NotAffectedByMaxRequestBodyLimit() { var upgraded = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously); @@ -155,7 +154,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task OpaqueUpgrade_WithOnStarting_CallbackCalled() { var callbackCalled = false; @@ -184,7 +183,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalTheory] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] // See HTTP_VERB for known verbs [InlineData("UNKNOWN", null)] [InlineData("INVALID", null)] @@ -242,7 +241,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys } [ConditionalTheory] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] // Http.Sys returns a 411 Length Required if PUT or POST does not specify content-length or chunked. [InlineData("POST", "Content-Length: 10")] [InlineData("POST", "Transfer-Encoding: chunked")] diff --git a/src/Servers/HttpSys/test/FunctionalTests/ResponseBodyTests.cs b/src/Servers/HttpSys/test/FunctionalTests/ResponseBodyTests.cs index 4a45a81a5d..bd73e39946 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/ResponseBodyTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/ResponseBodyTests.cs @@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys return Task.CompletedTask; }); await httpContext.Response.StartAsync(); + Assert.True(httpContext.Response.HasStarted); Assert.True(httpContext.Response.Headers.IsReadOnly); await startingTcs.Task.WithTimeout(); await httpContext.Response.WriteAsync("Hello World"); @@ -58,6 +59,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys return Task.CompletedTask; }); await httpContext.Response.CompleteAsync(); + Assert.True(httpContext.Response.HasStarted); Assert.True(httpContext.Response.Headers.IsReadOnly); await startingTcs.Task.WithTimeout(); await responseReceived.Task.WithTimeout(); diff --git a/src/Servers/HttpSys/test/FunctionalTests/ResponseCachingTests.cs b/src/Servers/HttpSys/test/FunctionalTests/ResponseCachingTests.cs index bda37a76c5..47c44ab938 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/ResponseCachingTests.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/ResponseCachingTests.cs @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.FunctionalTests } [ConditionalFact] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win2008R2, WindowsVersions.Win7, SkipReason = "Content type not required for caching on Win7 and Win2008R2.")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "Content type not required for caching on Win7.")] public async Task Caching_WithoutContentType_NotCached() { var requestCount = 1; diff --git a/src/Servers/HttpSys/test/FunctionalTests/ResponseTrailersTests.cs b/src/Servers/HttpSys/test/FunctionalTests/ResponseTrailersTests.cs new file mode 100644 index 0000000000..637220a990 --- /dev/null +++ b/src/Servers/HttpSys/test/FunctionalTests/ResponseTrailersTests.cs @@ -0,0 +1,368 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.HttpSys.Internal; +using Microsoft.AspNetCore.Testing; +using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; +using Xunit; + +namespace Microsoft.AspNetCore.Server.HttpSys +{ + public class ResponseTrailersTests + { + [ConditionalFact] + public async Task ResponseTrailers_HTTP11_TrailersNotAvailable() + { + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + Assert.Equal("HTTP/1.1", httpContext.Request.Protocol); + Assert.False(httpContext.Response.SupportsTrailers()); + return Task.FromResult(0); + })) + { + var response = await SendRequestAsync(address, http2: false); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version11, response.Version); + Assert.Empty(response.TrailingHeaders); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_HTTP2_TrailersAvailable() + { + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + Assert.Equal("HTTP/2", httpContext.Request.Protocol); + Assert.True(httpContext.Response.SupportsTrailers()); + return Task.FromResult(0); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Empty(response.TrailingHeaders); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_ProhibitedTrailers_Blocked() + { + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + Assert.True(httpContext.Response.SupportsTrailers()); + foreach (var header in HeaderCollection.DisallowedTrailers) + { + Assert.Throws<InvalidOperationException>(() => httpContext.Response.AppendTrailer(header, "value")); + } + return Task.FromResult(0); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Empty(response.TrailingHeaders); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_NoBody_TrailersSent() + { + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.DeclareTrailer("trailername"); + httpContext.Response.AppendTrailer("trailername", "TrailerValue"); + return Task.FromResult(0); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.NotEmpty(response.TrailingHeaders); + Assert.Equal("TrailerValue", response.TrailingHeaders.GetValues("TrailerName").Single()); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_WithBody_TrailersSent() + { + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + await httpContext.Response.WriteAsync("Hello World"); + httpContext.Response.AppendTrailer("TrailerName", "Trailer Value"); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Equal("Hello World", await response.Content.ReadAsStringAsync()); + Assert.NotEmpty(response.TrailingHeaders); + Assert.Equal("Trailer Value", response.TrailingHeaders.GetValues("TrailerName").Single()); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_WithContentLengthBody_TrailersNotSent() + { + var body = "Hello World"; + var responseFinished = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + httpContext.Response.ContentLength = body.Length; + await httpContext.Response.WriteAsync(body); + try + { + Assert.Throws<InvalidOperationException>(() => httpContext.Response.AppendTrailer("TrailerName", "Trailer Value")); + responseFinished.SetResult(0); + } + catch (Exception ex) + { + responseFinished.SetException(ex); + } + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Equal(body.Length.ToString(CultureInfo.InvariantCulture), response.Content.Headers.GetValues(HeaderNames.ContentLength).Single()); + Assert.Equal(body, await response.Content.ReadAsStringAsync()); + Assert.Empty(response.TrailingHeaders); + await responseFinished.Task; + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_WithTrailersBeforeContentLengthBody_TrailersSent() + { + var body = "Hello World"; + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + httpContext.Response.ContentLength = body.Length * 2; + await httpContext.Response.WriteAsync(body); + httpContext.Response.AppendTrailer("TrailerName", "Trailer Value"); + await httpContext.Response.WriteAsync(body); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + // Avoid HttpContent's automatic content-length calculation. + Assert.True(response.Content.Headers.TryGetValues(HeaderNames.ContentLength, out var contentLength), HeaderNames.ContentLength); + Assert.Equal((2 * body.Length).ToString(CultureInfo.InvariantCulture), contentLength.First()); + Assert.Equal(body + body, await response.Content.ReadAsStringAsync()); + Assert.NotEmpty(response.TrailingHeaders); + Assert.Equal("Trailer Value", response.TrailingHeaders.GetValues("TrailerName").Single()); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_WithContentLengthBodyAndDeclared_TrailersSent() + { + var body = "Hello World"; + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + httpContext.Response.ContentLength = body.Length; + httpContext.Response.DeclareTrailer("TrailerName"); + await httpContext.Response.WriteAsync(body); + httpContext.Response.AppendTrailer("TrailerName", "Trailer Value"); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + // Avoid HttpContent's automatic content-length calculation. + Assert.True(response.Content.Headers.TryGetValues(HeaderNames.ContentLength, out var contentLength), HeaderNames.ContentLength); + Assert.Equal(body.Length.ToString(CultureInfo.InvariantCulture), contentLength.First()); + Assert.Equal("TrailerName", response.Headers.Trailer.Single()); + Assert.Equal(body, await response.Content.ReadAsStringAsync()); + Assert.NotEmpty(response.TrailingHeaders); + Assert.Equal("Trailer Value", response.TrailingHeaders.GetValues("TrailerName").Single()); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_WithContentLengthBodyAndDeclaredButMissingTrailers_Completes() + { + var body = "Hello World"; + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + httpContext.Response.ContentLength = body.Length; + httpContext.Response.DeclareTrailer("TrailerName"); + await httpContext.Response.WriteAsync(body); + // If we declare trailers but don't send any make sure it completes anyways. + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + // Avoid HttpContent's automatic content-length calculation. + Assert.True(response.Content.Headers.TryGetValues(HeaderNames.ContentLength, out var contentLength), HeaderNames.ContentLength); + Assert.Equal(body.Length.ToString(CultureInfo.InvariantCulture), contentLength.First()); + Assert.Equal("TrailerName", response.Headers.Trailer.Single()); + Assert.Equal(body, await response.Content.ReadAsStringAsync()); + Assert.Empty(response.TrailingHeaders); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_CompleteAsyncNoBody_TrailersSent() + { + var trailersReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + httpContext.Response.AppendTrailer("trailername", "TrailerValue"); + await httpContext.Response.CompleteAsync(); + await trailersReceived.Task.WithTimeout(); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.NotEmpty(response.TrailingHeaders); + Assert.Equal("TrailerValue", response.TrailingHeaders.GetValues("TrailerName").Single()); + trailersReceived.SetResult(0); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_CompleteAsyncWithBody_TrailersSent() + { + var trailersReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + using (Utilities.CreateDynamicHttpsServer(out var address, async httpContext => + { + await httpContext.Response.WriteAsync("Hello World"); + httpContext.Response.AppendTrailer("TrailerName", "Trailer Value"); + await httpContext.Response.CompleteAsync(); + await trailersReceived.Task.WithTimeout(); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Equal("Hello World", await response.Content.ReadAsStringAsync()); + Assert.NotEmpty(response.TrailingHeaders); + Assert.Equal("Trailer Value", response.TrailingHeaders.GetValues("TrailerName").Single()); + trailersReceived.SetResult(0); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_MultipleValues_SentAsSeperateHeaders() + { + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.AppendTrailer("trailername", new StringValues(new[] { "TrailerValue0", "TrailerValue1" })); + return Task.FromResult(0); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.NotEmpty(response.TrailingHeaders); + // We can't actually assert they are sent as seperate headers using HttpClient, we'd have to write a lower level test + // that read the header frames directly. + Assert.Equal(new[] { "TrailerValue0", "TrailerValue1" }, response.TrailingHeaders.GetValues("TrailerName")); + } + } + + [ConditionalFact] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_LargeTrailers_Success() + { + var values = new[] { + new string('a', 1024), + new string('b', 1024 * 4), + new string('c', 1024 * 8), + new string('d', 1024 * 16), + new string('e', 1024 * 32), + new string('f', 1024 * 64 - 1) }; // Max header size + + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.AppendTrailer("ThisIsALongerHeaderNameThatStillWorksForReals", new StringValues(values)); + return Task.FromResult(0); + })) + { + var response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.NotEmpty(response.TrailingHeaders); + // We can't actually assert they are sent in multiple frames using HttpClient, we'd have to write a lower level test + // that read the header frames directly. We at least verify that really large values work. + Assert.Equal(values, response.TrailingHeaders.GetValues("ThisIsALongerHeaderNameThatStillWorksForReals")); + } + } + + [ConditionalTheory, MemberData(nameof(NullHeaderData))] + [MinimumOSVersion(OperatingSystems.Windows, "10.0.19529", SkipReason = "Requires HTTP/2 Trailers support.")] + public async Task ResponseTrailers_NullValues_Ignored(string headerName, StringValues headerValue, StringValues expectedValue) + { + using (Utilities.CreateDynamicHttpsServer(out var address, httpContext => + { + httpContext.Response.AppendTrailer(headerName, headerValue); + return Task.FromResult(0); + })) + { + HttpResponseMessage response = await SendRequestAsync(address); + response.EnsureSuccessStatusCode(); + var headers = response.TrailingHeaders; + + if (StringValues.IsNullOrEmpty(expectedValue)) + { + Assert.False(headers.Contains(headerName)); + } + else + { + Assert.True(headers.Contains(headerName)); + Assert.Equal(headers.GetValues(headerName), expectedValue); + } + } + } + + public static TheoryData<string, StringValues, StringValues> NullHeaderData + { + get + { + var dataset = new TheoryData<string, StringValues, StringValues>(); + + dataset.Add("NullString", (string)null, (string)null); + dataset.Add("EmptyString", "", ""); + dataset.Add("NullStringArray", new string[] { null }, ""); + dataset.Add("EmptyStringArray", new string[] { "" }, ""); + dataset.Add("MixedStringArray", new string[] { null, "" }, new string[] { "", "" }); + dataset.Add("WithValidStrings", new string[] { null, "Value", "" }, new string[] { "", "Value", "" }); + + return dataset; + } + } + + private async Task<HttpResponseMessage> SendRequestAsync(string uri, bool http2 = true) + { + var handler = new HttpClientHandler(); + handler.MaxResponseHeadersLength = 128; + handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; + using HttpClient client = new HttpClient(handler); + client.DefaultRequestVersion = http2 ? HttpVersion.Version20 : HttpVersion.Version11; + return await client.GetAsync(uri); + } + } +} diff --git a/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs b/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs index 8ba9e7b39a..a347ce427f 100644 --- a/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs +++ b/src/Servers/HttpSys/test/FunctionalTests/Utilities.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; @@ -21,11 +22,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys { // When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free // ports during dynamic port allocation. - private const int BasePort = 5001; - private const int MaxPort = 8000; private const int BaseHttpsPort = 44300; private const int MaxHttpsPort = 44399; - private static int NextPort = BasePort; private static int NextHttpsPort = BaseHttpsPort; private static object PortLock = new object(); internal static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(15); @@ -84,39 +82,26 @@ namespace Microsoft.AspNetCore.Server.HttpSys internal static IWebHost CreateDynamicHost(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app) { - lock (PortLock) - { - while (NextPort < MaxPort) + var prefix = UrlPrefix.Create("http", "localhost", "0", basePath); + + var builder = new WebHostBuilder() + .UseHttpSys(options => { - var port = NextPort++; - var prefix = UrlPrefix.Create("http", "localhost", port, basePath); - root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; - baseAddress = prefix.ToString(); + options.UrlPrefixes.Add(prefix); + configureOptions(options); + }) + .Configure(appBuilder => appBuilder.Run(app)); - var builder = new WebHostBuilder() - .UseHttpSys(options => - { - options.UrlPrefixes.Add(prefix); - configureOptions(options); - }) - .Configure(appBuilder => appBuilder.Run(app)); + var host = builder.Build(); - var host = builder.Build(); + host.Start(); + var options = host.Services.GetRequiredService<IOptions<HttpSysOptions>>(); + prefix = options.Value.UrlPrefixes.First(); // Has new port + root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; + baseAddress = prefix.ToString(); - try - { - host.Start(); - return host; - } - catch (HttpSysException) - { - } - - } - NextPort = BasePort; - } - throw new Exception("Failed to locate a free port."); + return host; } internal static MessagePump CreatePump() @@ -131,30 +116,17 @@ namespace Microsoft.AspNetCore.Server.HttpSys internal static IServer CreateDynamicHttpServer(string basePath, out string root, out string baseAddress, Action<HttpSysOptions> configureOptions, RequestDelegate app) { - lock (PortLock) - { - while (NextPort < MaxPort) - { + var prefix = UrlPrefix.Create("http", "localhost", "0", basePath); - var port = NextPort++; - var prefix = UrlPrefix.Create("http", "localhost", port, basePath); - root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; - baseAddress = prefix.ToString(); + var server = CreatePump(configureOptions); + server.Features.Get<IServerAddressesFeature>().Addresses.Add(prefix.ToString()); + server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait(); - var server = CreatePump(configureOptions); - server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress); - try - { - server.StartAsync(new DummyApplication(app), CancellationToken.None).Wait(); - return server; - } - catch (HttpSysException) - { - } - } - NextPort = BasePort; - } - throw new Exception("Failed to locate a free port."); + prefix = server.Listener.Options.UrlPrefixes.First(); // Has new port + root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; + baseAddress = prefix.ToString(); + + return server; } internal static IServer CreateDynamicHttpsServer(out string baseAddress, RequestDelegate app) diff --git a/src/Servers/HttpSys/test/Tests/UrlPrefixTests.cs b/src/Servers/HttpSys/test/Tests/UrlPrefixTests.cs index 8614ac36db..20d0f0713f 100644 --- a/src/Servers/HttpSys/test/Tests/UrlPrefixTests.cs +++ b/src/Servers/HttpSys/test/Tests/UrlPrefixTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h index 05fd514bea..517f00d15e 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/CommonLib/config_utility.h @@ -15,6 +15,7 @@ class ConfigUtility #define CS_ASPNETCORE_HANDLER_VERSION L"handlerVersion" #define CS_ASPNETCORE_DEBUG_FILE L"debugFile" #define CS_ASPNETCORE_ENABLE_OUT_OF_PROCESS_CONSOLE_REDIRECTION L"enableOutOfProcessConsoleRedirection" + #define CS_ASPNETCORE_FORWARD_RESPONSE_CONNECTION_HEADER L"forwardResponseConnectionHeader" #define CS_ASPNETCORE_DEBUG_LEVEL L"debugLevel" #define CS_ASPNETCORE_HANDLER_SETTINGS_NAME L"name" #define CS_ASPNETCORE_HANDLER_SETTINGS_VALUE L"value" @@ -48,6 +49,13 @@ public: return FindKeyValuePair(pElement, CS_ASPNETCORE_ENABLE_OUT_OF_PROCESS_CONSOLE_REDIRECTION, strEnableOutOfProcessConsoleRedirection); } + static + HRESULT + FindForwardResponseConnectionHeader(IAppHostElement* pElement, STRU& strForwardResponseConnectionHeader) + { + return FindKeyValuePair(pElement, CS_ASPNETCORE_FORWARD_RESPONSE_CONNECTION_HEADER, strForwardResponseConnectionHeader); + } + private: static HRESULT diff --git a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp index 4fbf2abf40..82737cf24b 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.cpp @@ -55,6 +55,7 @@ FORWARDING_HANDLER::FORWARDING_HANDLER( LOG_TRACE(L"FORWARDING_HANDLER::FORWARDING_HANDLER"); m_fWebSocketSupported = m_pApplication->QueryWebsocketStatus(); + m_fForwardResponseConnectionHeader = m_pApplication->QueryConfig()->QueryForwardResponseConnectionHeader()->Equals(L"true", /* ignoreCase */ 1); InitializeSRWLock(&m_RequestLock); } @@ -2212,10 +2213,14 @@ FORWARDING_HANDLER::SetStatusAndHeaders( break; } __fallthrough; - case HttpHeaderConnection: case HttpHeaderDate: continue; - + case HttpHeaderConnection: + if (!m_fForwardResponseConnectionHeader) + { + continue; + } + break; case HttpHeaderServer: fServerHeaderPresent = TRUE; break; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h index cc855dfcf2..c564a7b4f0 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/OutOfProcessRequestHandler/forwardinghandler.h @@ -179,6 +179,7 @@ private: HINTERNET m_hRequest; FORWARDING_REQUEST_STATUS m_RequestStatus; + BOOL m_fForwardResponseConnectionHeader; BOOL m_fWebSocketEnabled; BOOL m_fWebSocketSupported; BOOL m_fResponseHeadersReceivedAndSet; diff --git a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp index d3a705e9a2..437e3b1596 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.cpp @@ -385,6 +385,12 @@ REQUESTHANDLER_CONFIG::Populate( goto Finished; } + hr = ConfigUtility::FindForwardResponseConnectionHeader(pAspNetCoreElement, m_struForwardResponseConnectionHeader); + if (FAILED(hr)) + { + goto Finished; + } + Finished: if (pAspNetCoreElement != NULL) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h index 5f06c12695..1552e8d075 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h +++ b/src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/requesthandler_config.h @@ -224,6 +224,12 @@ public: return !m_fEnableOutOfProcessConsoleRedirection.Equals(L"false", 1); } + STRU* + QueryForwardResponseConnectionHeader() + { + return &m_struForwardResponseConnectionHeader; + } + protected: // @@ -255,6 +261,7 @@ protected: STRU m_struApplicationPhysicalPath; STRU m_struApplicationVirtualPath; STRU m_struConfigPath; + STRU m_struForwardResponseConnectionHeader; BOOL m_fStdoutLogEnabled; BOOL m_fForwardWindowsAuthToken; BOOL m_fDisableStartUpErrorPage; diff --git a/src/Servers/IIS/IIS/benchmarks/IIS.Performance/StartupTimeBenchmark.cs b/src/Servers/IIS/IIS/benchmarks/IIS.Performance/StartupTimeBenchmark.cs index 3cb8d3a1c8..dd561126d6 100644 --- a/src/Servers/IIS/IIS/benchmarks/IIS.Performance/StartupTimeBenchmark.cs +++ b/src/Servers/IIS/IIS/benchmarks/IIS.Performance/StartupTimeBenchmark.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Performance public void Setup() { // Deployers do not work in distributed environments -// see https://github.com/aspnet/AspNetCore/issues/10268 and https://github.com/aspnet/Extensions/issues/1697 +// see https://github.com/dotnet/aspnetcore/issues/10268 and https://github.com/dotnet/extensions/issues/1697 #pragma warning disable 0618 var deploymentParameters = new DeploymentParameters(Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"), "test/testassets/InProcessWebSite"), ServerType.IISExpress, diff --git a/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp.cs b/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp.cs index 635097115d..479bfe8e6c 100644 --- a/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp.cs +++ b/src/Servers/IIS/IIS/ref/Microsoft.AspNetCore.Server.IIS.netcoreapp.cs @@ -6,9 +6,9 @@ namespace Microsoft.AspNetCore.Builder public partial class IISServerOptions { public IISServerOptions() { } - public bool AllowSynchronousIO { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string AuthenticationDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool AutomaticAuthentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool AllowSynchronousIO { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string AuthenticationDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool AutomaticAuthentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public long? MaxRequestBodySize { get { throw null; } set { } } } } @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IIS public sealed partial class BadHttpRequestException : System.IO.IOException { internal BadHttpRequestException() { } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class HttpContextExtensions { diff --git a/src/Servers/IIS/IIS/src/Core/DuplexStream.cs b/src/Servers/IIS/IIS/src/Core/DuplexStream.cs index 8ff01c778f..73dbd4cbb9 100644 --- a/src/Servers/IIS/IIS/src/Core/DuplexStream.cs +++ b/src/Servers/IIS/IIS/src/Core/DuplexStream.cs @@ -60,9 +60,29 @@ namespace Microsoft.AspNetCore.Server.IIS.Core return _requestBody.ReadAsync(buffer, offset, count, cancellationToken); } + public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) + { + return _requestBody.ReadAsync(buffer, cancellationToken); + } + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { return _responseBody.WriteAsync(buffer, offset, count, cancellationToken); } + + public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) + { + return _responseBody.WriteAsync(buffer, cancellationToken); + } + + public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) + { + return _requestBody.CopyToAsync(destination, bufferSize, cancellationToken); + } + + public override Task FlushAsync(CancellationToken cancellationToken) + { + return _responseBody.FlushAsync(cancellationToken); + } } } diff --git a/src/Servers/IIS/IIS/src/Core/HttpRequestStream.cs b/src/Servers/IIS/IIS/src/Core/HttpRequestStream.cs index 9fa5d7405e..8d90fd69a5 100644 --- a/src/Servers/IIS/IIS/src/Core/HttpRequestStream.cs +++ b/src/Servers/IIS/IIS/src/Core/HttpRequestStream.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.IO; using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; @@ -35,40 +36,12 @@ namespace Microsoft.AspNetCore.Server.IIS.Core public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = ReadAsync(buffer, offset, count, default(CancellationToken), state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); } public override int EndRead(IAsyncResult asyncResult) { - return ((Task<int>)asyncResult).GetAwaiter().GetResult(); - } - - private Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<int>(state); - var task = ReadAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<int>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(task2.Result); - } - }, tcs, cancellationToken); - return tcs.Task; + return TaskToApm.End<int>(asyncResult); } public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) @@ -97,6 +70,18 @@ namespace Microsoft.AspNetCore.Server.IIS.Core } } + public override async Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) + { + try + { + await _body.CopyToAsync(destination, cancellationToken); + } + catch (ConnectionAbortedException ex) + { + throw new TaskCanceledException("The request was aborted", ex); + } + } + public void StartAcceptingReads(IISHttpContext body) { // Only start if not aborted diff --git a/src/Servers/IIS/IIS/src/Core/HttpResponseStream.cs b/src/Servers/IIS/IIS/src/Core/HttpResponseStream.cs index 739b6b16f5..b1d0c1f22a 100644 --- a/src/Servers/IIS/IIS/src/Core/HttpResponseStream.cs +++ b/src/Servers/IIS/IIS/src/Core/HttpResponseStream.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core public override void Flush() { - FlushAsync(default(CancellationToken)).GetAwaiter().GetResult(); + FlushAsync(default).GetAwaiter().GetResult(); } public override Task FlushAsync(CancellationToken cancellationToken) @@ -41,45 +41,17 @@ namespace Microsoft.AspNetCore.Server.IIS.Core throw new InvalidOperationException(CoreStrings.SynchronousWritesDisallowed); } - WriteAsync(buffer, offset, count, default(CancellationToken)).GetAwaiter().GetResult(); + WriteAsync(buffer, offset, count, default).GetAwaiter().GetResult(); } public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = WriteAsync(buffer, offset, count, default(CancellationToken), state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); } public override void EndWrite(IAsyncResult asyncResult) { - ((Task<object>)asyncResult).GetAwaiter().GetResult(); - } - - private Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<object>(state); - var task = WriteAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<object>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(null); - } - }, tcs, cancellationToken); - return tcs.Task; + TaskToApm.End(asyncResult); } public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContext.FeatureCollection.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContext.FeatureCollection.cs index cab956dd0a..6635385e7f 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContext.FeatureCollection.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContext.FeatureCollection.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features.Authentication; +using Microsoft.AspNetCore.HttpSys.Internal; using Microsoft.AspNetCore.Server.IIS.Core.IO; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Logging; @@ -37,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core // then the list of `implementedFeatures` in the generated code project MUST also be updated. private int _featureRevision; - private string _httpProtocolVersion = null; + private string _httpProtocolVersion; private X509Certificate2 _certificate; private List<KeyValuePair<Type, object>> MaybeExtra; @@ -86,30 +87,8 @@ namespace Microsoft.AspNetCore.Server.IIS.Core string IHttpRequestFeature.Protocol { - get - { - if (_httpProtocolVersion == null) - { - var protocol = HttpVersion; - if (protocol.Major == 1 && protocol.Minor == 1) - { - _httpProtocolVersion = "HTTP/1.1"; - } - else if (protocol.Major == 1 && protocol.Minor == 0) - { - _httpProtocolVersion = "HTTP/1.0"; - } - else - { - _httpProtocolVersion = "HTTP/" + protocol.ToString(2); - } - } - return _httpProtocolVersion; - } - set - { - _httpProtocolVersion = value; - } + get => _httpProtocolVersion ??= HttpVersion.GetHttpProtocolVersion(); + set => _httpProtocolVersion = value; } string IHttpRequestFeature.Scheme diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs index 68141058c5..5f831eb01a 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContext.IO.cs @@ -3,11 +3,10 @@ using System; using System.Buffers; -using System.Net.Http; +using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; namespace Microsoft.AspNetCore.Server.IIS.Core @@ -54,6 +53,16 @@ namespace Microsoft.AspNetCore.Server.IIS.Core } } + internal Task CopyToAsync(Stream destination, CancellationToken cancellationToken) + { + if (!HasStartedConsumingRequestBody) + { + InitializeRequestIO(); + } + + return _bodyInputPipe.Reader.CopyToAsync(destination, cancellationToken); + } + /// <summary> /// Writes data to the output pipe. /// </summary> diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs index cae357e776..74f0cbae6b 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContext.cs @@ -409,7 +409,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core } } - public abstract Task<bool> ProcessRequestAsync(); + public abstract Task ProcessRequestAsync(); public void OnStarting(Func<object, Task> callback, object state) { @@ -599,10 +599,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core private async Task HandleRequest() { - bool successfulRequest = false; try { - successfulRequest = await ProcessRequestAsync(); + await ProcessRequestAsync(); } catch (Exception ex) { @@ -610,19 +609,9 @@ namespace Microsoft.AspNetCore.Server.IIS.Core } finally { - // Post completion after completing the request to resume the state machine - PostCompletion(ConvertRequestCompletionResults(successfulRequest)); - - // Dispose the context Dispose(); } } - - private static NativeMethods.REQUEST_NOTIFICATION_STATUS ConvertRequestCompletionResults(bool success) - { - return success ? NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_CONTINUE - : NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST; - } } } diff --git a/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs b/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs index 372eadfa71..060f105233 100644 --- a/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs +++ b/src/Servers/IIS/IIS/src/Core/IISHttpContextOfT.cs @@ -21,32 +21,33 @@ namespace Microsoft.AspNetCore.Server.IIS.Core _application = application; } - public override async Task<bool> ProcessRequestAsync() + public override async Task ProcessRequestAsync() { - InitializeContext(); - var context = default(TContext); var success = true; try { - context = _application.CreateContext(this); + InitializeContext(); + + try + { + context = _application.CreateContext(this); + + await _application.ProcessRequestAsync(context); + } + catch (BadHttpRequestException ex) + { + SetBadRequestState(ex); + ReportApplicationError(ex); + success = false; + } + catch (Exception ex) + { + ReportApplicationError(ex); + success = false; + } - await _application.ProcessRequestAsync(context); - } - catch (BadHttpRequestException ex) - { - SetBadRequestState(ex); - ReportApplicationError(ex); - success = false; - } - catch (Exception ex) - { - ReportApplicationError(ex); - success = false; - } - finally - { await CompleteResponseBodyAsync(); _streams.Stop(); @@ -56,36 +57,18 @@ namespace Microsoft.AspNetCore.Server.IIS.Core // Dispose } - if (_onCompleted != null) + if (!_requestAborted) { - await FireOnCompleted(); + await ProduceEnd(); + } + else if (!HasResponseStarted && _requestRejectedException == null) + { + // If the request was aborted and no response was sent, there's no + // meaningful status code to log. + StatusCode = 0; + success = false; } - } - if (!_requestAborted) - { - await ProduceEnd(); - } - else if (!HasResponseStarted && _requestRejectedException == null) - { - // If the request was aborted and no response was sent, there's no - // meaningful status code to log. - StatusCode = 0; - success = false; - } - - try - { - _application.DisposeContext(context, _applicationException); - } - catch (Exception ex) - { - // TODO Log this - _applicationException = _applicationException ?? ex; - success = false; - } - finally - { // Complete response writer and request reader pipe sides _bodyOutput.Dispose(); _bodyInputPipe?.Reader.Complete(); @@ -104,7 +87,36 @@ namespace Microsoft.AspNetCore.Server.IIS.Core await _readBodyTask; } } - return success; + catch (Exception ex) + { + success = false; + ReportApplicationError(ex); + } + finally + { + // We're done with anything that touches the request or response, unblock the client. + PostCompletion(ConvertRequestCompletionResults(success)); + + if (_onCompleted != null) + { + await FireOnCompleted(); + } + + try + { + _application.DisposeContext(context, _applicationException); + } + catch (Exception ex) + { + ReportApplicationError(ex); + } + } + } + + private static NativeMethods.REQUEST_NOTIFICATION_STATUS ConvertRequestCompletionResults(bool success) + { + return success ? NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_CONTINUE + : NativeMethods.REQUEST_NOTIFICATION_STATUS.RQ_NOTIFICATION_FINISH_REQUEST; } } } diff --git a/src/Servers/IIS/IIS/src/Core/OutputProducer.cs b/src/Servers/IIS/IIS/src/Core/OutputProducer.cs index 2dee24f7b9..7d295c6614 100644 --- a/src/Servers/IIS/IIS/src/Core/OutputProducer.cs +++ b/src/Servers/IIS/IIS/src/Core/OutputProducer.cs @@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Server.IIS.Core private readonly Pipe _pipe; // https://github.com/dotnet/corefxlab/issues/1334 - // https://github.com/aspnet/AspNetCore/issues/8843 + // https://github.com/dotnet/aspnetcore/issues/8843 // Pipelines don't support multiple awaiters on flush. This is temporary until it does. // _lastFlushTask field should only be get or set under the _flushLock. private readonly object _flushLock = new object(); diff --git a/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj b/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj index 06fe1aa203..a95e4ec56a 100644 --- a/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj +++ b/src/Servers/IIS/IIS/src/Microsoft.AspNetCore.Server.IIS.csproj @@ -19,6 +19,7 @@ <Compile Include="$(SharedSourceRoot)StackTrace\**\*.cs" LinkBase="Shared\" /> <Compile Include="$(SharedSourceRoot)RazorViews\*.cs" LinkBase="Shared\" /> <Compile Include="$(SharedSourceRoot)ErrorPage\*.cs" LinkBase="Shared\" /> + <Compile Include="$(RepoRoot)src\Shared\TaskToApm.cs" Link="Shared\TaskToApm.cs" /> </ItemGroup> <Target Name="ValidateNativeComponentsBuilt" AfterTargets="Build" > diff --git a/src/Servers/IIS/IIS/src/StartupHook.cs b/src/Servers/IIS/IIS/src/StartupHook.cs index 5f8f3edf5a..10fe17b4d2 100644 --- a/src/Servers/IIS/IIS/src/StartupHook.cs +++ b/src/Servers/IIS/IIS/src/StartupHook.cs @@ -81,6 +81,7 @@ internal class StartupHook var exceptionDetailProvider = new ExceptionDetailsProvider( new PhysicalFileProvider(contentRoot), + logger: null, sourceCodeLineCount: 6); // The startup hook is only present when detailed errors are allowed, so diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/AppOfflineTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/AppOfflineTests.cs index 4bd29675ae..13409c545d 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/AppOfflineTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/AppOfflineTests.cs @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests DeletePublishOutput(deploymentResult); } - [ConditionalFact(Skip = "https://github.com/aspnet/AspNetCore/issues/3835")] + [ConditionalFact(Skip = "https://github.com/dotnet/aspnetcore/issues/3835")] public async Task AppOfflineDroppedWhileSiteFailedToStartInRequestHandler_SiteStops_InProcess() { var deploymentResult = await DeployApp(HostingModel.InProcess); @@ -211,7 +211,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests [ConditionalTheory] [InlineData(HostingModel.InProcess)] [InlineData(HostingModel.OutOfProcess)] - [Flaky("https://github.com/aspnet/AspNetCore/issues/7075", FlakyOn.All)] + [Flaky("https://github.com/dotnet/aspnetcore/issues/7075", FlakyOn.All)] public async Task AppOfflineAddedAndRemovedStress(HostingModel hostingModel) { var deploymentResult = await AssertStarts(hostingModel); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/BasicAuthTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/BasicAuthTests.cs index 6130cdf882..36520369a6 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/BasicAuthTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/BasicAuthTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithApplicationTypes(ApplicationType.Portable) .WithAllHostingModels(); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientCertificateTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientCertificateTests.cs index ccc4ea6458..b0847f84a1 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientCertificateTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/ClientCertificateTests.cs @@ -29,13 +29,13 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllHostingModels(); [ConditionalTheory] [MemberData(nameof(TestVariants))] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public Task HttpsNoClientCert_NoClientCert(TestVariant variant) { return ClientCertTest(variant, sendClientCert: false); @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests [ConditionalTheory] [MemberData(nameof(TestVariants))] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public Task HttpsClientCert_GetCertInformation(TestVariant variant) { return ClientCertTest(variant, sendClientCert: true); @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests var port = TestPortHelper.GetNextSSLPort(); var deploymentParameters = Fixture.GetBaseDeploymentParameters(variant); deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/"; - deploymentParameters.AddHttpsToServerConfig(); + deploymentParameters.AddHttpsWithClientCertToServerConfig(); var handler = new HttpClientHandler { diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/CommonStartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/CommonStartupTests.cs index 82df45fdbf..38f4dae818 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/CommonStartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/CommonStartupTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllHostingModels(); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs index c93faacdc0..5b2323223a 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/HttpsTests.cs @@ -26,13 +26,13 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllHostingModels(); [ConditionalTheory] [MemberData(nameof(TestVariants))] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, WindowsVersions.Win2008R2)] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8)] public async Task HttpsHelloWorld(TestVariant variant) { var port = TestPortHelper.GetNextSSLPort(); @@ -80,6 +80,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess); deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/"; deploymentParameters.AddHttpsToServerConfig(); + deploymentParameters.SetWindowsAuth(false); deploymentParameters.AddServerConfigAction( (element, root) => { element.Descendants("site").Single().Element("application").SetAttributeValue("path", "/" + appName); @@ -88,11 +89,29 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests var deploymentResult = await DeployAsync(deploymentParameters); var client = CreateNonValidatingClient(deploymentResult); - Assert.Equal(deploymentParameters.ApplicationBaseUriHint + appName, await client.GetStringAsync($"/{appName}/ServerAddresses")); } [ConditionalFact] + [RequiresNewHandler] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10)] + public async Task CheckProtocolIsHttp2() + { + var port = TestPortHelper.GetNextSSLPort(); + var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess); + deploymentParameters.ApplicationBaseUriHint = $"https://localhost:{port}/"; + deploymentParameters.AddHttpsToServerConfig(); + deploymentParameters.SetWindowsAuth(false); + + var deploymentResult = await DeployAsync(deploymentParameters); + var client = CreateNonValidatingClient(deploymentResult); + client.DefaultRequestVersion = HttpVersion.Version20; + + Assert.Equal("HTTP/2", await client.GetStringAsync($"/CheckProtocol")); + } + + [ConditionalFact] + [RequiresNewHandler] [RequiresNewShim] public async Task AncmHttpsPortCanBeOverriden() { @@ -188,6 +207,35 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests Assert.Equal("NOVALUE", await client.GetStringAsync("/ANCM_HTTPS_PORT")); } + [ConditionalFact] + [RequiresNewHandler] + [RequiresNewShim] + public async Task SetsConnectionCloseHeader() + { + // Only tests OutOfProcess as the Connection header is removed for out of process and not inprocess. + // This test checks a quirk to allow setting the Connection header. + var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess); + + deploymentParameters.HandlerSettings["forwardResponseConnectionHeader"] = "true"; + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("ConnectionClose"); + Assert.Equal(true, response.Headers.ConnectionClose); + } + + [ConditionalFact] + [RequiresNewHandler] + [RequiresNewShim] + public async Task ConnectionCloseIsNotPropagated() + { + var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess); + + var deploymentResult = await DeployAsync(deploymentParameters); + + var response = await deploymentResult.HttpClient.GetAsync("ConnectionClose"); + Assert.Null(response.Headers.ConnectionClose); + } + private static HttpClient CreateNonValidatingClient(IISDeploymentResult deploymentResult) { var handler = new HttpClientHandler diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseBodyTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseBodyTests.cs index d45024441e..d1867c8044 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseBodyTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/ResponseBodyTests.cs @@ -30,5 +30,12 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess { Assert.Equal(20, (await _fixture.Client.GetByteArrayAsync($"/FlushedPipeAndThenUnflushedPipe")).Length); } + + [ConditionalFact] + [RequiresNewHandler] + public async Task ResponseBodyTest_BodyCompletionNotBlockedByOnCompleted() + { + Assert.Equal("SlowOnCompleted", await _fixture.Client.GetStringAsync($"/SlowOnCompleted")); + } } } diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs index 1c070242e0..810dbd90a9 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/StartupTests.cs @@ -172,7 +172,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAncmV2InProcess(); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs index 034cc48fd7..72fcdeefd5 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Inprocess/SynchronousReadAndWriteTests.cs @@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess } [ConditionalFact] + [Flaky("https://github.com/dotnet/aspnetcore/issues/7341", FlakyOn.Helix.All)] public async Task ReadAndWriteSynchronously() { for (int i = 0; i < 100; i++) diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs index 70f6a6b8b4..0993c4e2e8 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/LogFileTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes() .WithAllHostingModels(); diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs index 8557b89f94..969fc2c05b 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/AspNetCorePortTests.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithApplicationTypes(ApplicationType.Portable); public static IEnumerable<object[]> InvalidTestVariants diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs index deaf45f95a..2054011422 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/OutOfProcess/HelloWorldTest.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.OutOfProcess public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllApplicationTypes(); [ConditionalTheory] diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs index 8bf370e640..bbcb510945 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedApplicationPublisher.cs @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests private string GetProjectReferencePublishLocation(DeploymentParameters deploymentParameters) { // Deployers do not work in distributed environments -// see https://github.com/aspnet/AspNetCore/issues/10268 and https://github.com/aspnet/Extensions/issues/1697 +// see https://github.com/dotnet/aspnetcore/issues/10268 and https://github.com/dotnet/extensions/issues/1697 #pragma warning disable 0618 var testAssetsBasePath = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("IISIntegration"), "IIS", "test", "testassets", _applicationName); #pragma warning restore 0618 diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs index a0fd00f869..70a7606e31 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/PublishedSitesFixture.cs @@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests RuntimeFlavor = RuntimeFlavor.CoreClr, RuntimeArchitecture = RuntimeArchitecture.x64, HostingModel = hostingModel, - TargetFramework = Tfm.NetCoreApp31 + TargetFramework = Tfm.NetCoreApp50 }); } diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs index 645e595cbf..29d6f9c80c 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/Utilities/IISTestSiteFixture.cs @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { RuntimeArchitecture = RuntimeArchitecture.x64, RuntimeFlavor = RuntimeFlavor.CoreClr, - TargetFramework = Tfm.NetCoreApp31, + TargetFramework = Tfm.NetCoreApp50, HostingModel = HostingModel.InProcess, PublishApplicationBeforeDeployment = true, ApplicationPublisher = new PublishedApplicationPublisher(Helpers.GetInProcessTestSitesName()), diff --git a/src/Servers/IIS/IIS/test/Common.FunctionalTests/WindowsAuthTests.cs b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WindowsAuthTests.cs index f9716c2a26..e22f96dadc 100644 --- a/src/Servers/IIS/IIS/test/Common.FunctionalTests/WindowsAuthTests.cs +++ b/src/Servers/IIS/IIS/test/Common.FunctionalTests/WindowsAuthTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithApplicationTypes(ApplicationType.Portable) .WithAllHostingModels(); diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/ClientDisconnectTests.cs b/src/Servers/IIS/IIS/test/IIS.Tests/ClientDisconnectTests.cs index b662fd4732..a9b0cef7b6 100644 --- a/src/Servers/IIS/IIS/test/IIS.Tests/ClientDisconnectTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.Tests/ClientDisconnectTests.cs @@ -14,7 +14,7 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { [SkipIfHostableWebCoreNotAvailable] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "https://github.com/aspnet/IISIntegration/issues/866")] public class ClientDisconnectTests : StrictTestServerTests { [ConditionalFact] diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/ConnectionIdFeatureTests.cs b/src/Servers/IIS/IIS/test/IIS.Tests/ConnectionIdFeatureTests.cs index 8efb9601a3..7847fffccb 100644 --- a/src/Servers/IIS/IIS/test/IIS.Tests/ConnectionIdFeatureTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.Tests/ConnectionIdFeatureTests.cs @@ -9,7 +9,7 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { [SkipIfHostableWebCoreNotAvailable] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "https://github.com/aspnet/IISIntegration/issues/866")] public class ConnectionIdFeatureTests : StrictTestServerTests { [ConditionalFact] diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/HttpBodyControlFeatureTests.cs b/src/Servers/IIS/IIS/test/IIS.Tests/HttpBodyControlFeatureTests.cs index 981a3e6d45..1700351f6b 100644 --- a/src/Servers/IIS/IIS/test/IIS.Tests/HttpBodyControlFeatureTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.Tests/HttpBodyControlFeatureTests.cs @@ -10,7 +10,7 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { [SkipIfHostableWebCoreNotAvailable] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "https://github.com/aspnet/IISIntegration/issues/866")] public class HttpBodyControlFeatureTests : StrictTestServerTests { [ConditionalFact] diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/MaxRequestBodySizeTests.cs b/src/Servers/IIS/IIS/test/IIS.Tests/MaxRequestBodySizeTests.cs index 8bac31d82c..1f46ed1b4b 100644 --- a/src/Servers/IIS/IIS/test/IIS.Tests/MaxRequestBodySizeTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.Tests/MaxRequestBodySizeTests.cs @@ -15,7 +15,7 @@ using Xunit; namespace IIS.Tests { [SkipIfHostableWebCoreNotAvailable] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "https://github.com/aspnet/IISIntegration/issues/866")] public class MaxRequestBodySizeTests : LoggedTest { [ConditionalFact] diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs b/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs index 4b59d31298..c240382137 100644 --- a/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs +++ b/src/Servers/IIS/IIS/test/IIS.Tests/ResponseAbortTests.cs @@ -12,7 +12,7 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { [SkipIfHostableWebCoreNotAvailable] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "https://github.com/aspnet/IISIntegration/issues/866")] public class ResponseAbortTests : StrictTestServerTests { [ConditionalFact] diff --git a/src/Servers/IIS/IIS/test/IIS.Tests/TestServerTest.cs b/src/Servers/IIS/IIS/test/IIS.Tests/TestServerTest.cs index e350d679c2..55a4ad6995 100644 --- a/src/Servers/IIS/IIS/test/IIS.Tests/TestServerTest.cs +++ b/src/Servers/IIS/IIS/test/IIS.Tests/TestServerTest.cs @@ -10,7 +10,7 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { [SkipIfHostableWebCoreNotAvailable] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, "https://github.com/aspnet/IISIntegration/issues/866")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "https://github.com/aspnet/IISIntegration/issues/866")] public class TestServerTest : StrictTestServerTests { [ConditionalFact] diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs index 1ebc0981bd..4e75d204c8 100644 --- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs +++ b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/InProcess/WebSocketTests.cs @@ -13,7 +13,7 @@ using Xunit; namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests { [Collection(IISTestSiteCollection.Name)] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win7, SkipReason = "No supported on this platform")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win8, SkipReason = "No WebSocket supported on Win7")] public class WebSocketsTests { private readonly string _webSocketUri; diff --git a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs index 17f557a338..c63c777c80 100644 --- a/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs +++ b/src/Servers/IIS/IIS/test/IISExpress.FunctionalTests/OutOfProcess/NtlmAuthentationTest.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(DeployerSelector.ServerType) - .WithTfms(Tfm.NetCoreApp31); + .WithTfms(Tfm.NetCoreApp50); [ConditionalTheory] [RequiresIIS(IISCapability.WindowsAuthentication)] diff --git a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs index 7336dda665..95ae863ffd 100644 --- a/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs +++ b/src/Servers/IIS/IIS/test/testassets/InProcessWebSite/Startup.cs @@ -69,6 +69,11 @@ namespace TestSite await ctx.Response.WriteAsync(string.Join(",", serverAddresses.Addresses)); } + private async Task CheckProtocol(HttpContext ctx) + { + await ctx.Response.WriteAsync(ctx.Request.Protocol); + } + private async Task ConsoleWrite(HttpContext ctx) { Console.WriteLine("TEST MESSAGE"); @@ -145,6 +150,12 @@ namespace TestSite return Task.CompletedTask; } + public Task ConnectionClose(HttpContext context) + { + context.Response.Headers["connection"] = "close"; + return Task.CompletedTask; + } + public Task OverrideServer(HttpContext context) { context.Response.Headers["Server"] = "MyServer/7.8"; @@ -1005,5 +1016,12 @@ namespace TestSite await context.Response.WriteAsync(httpsPort.HasValue ? httpsPort.Value.ToString() : "NOVALUE"); } + + public async Task SlowOnCompleted(HttpContext context) + { + // This shouldn't block the response or the server from shutting down. + context.Response.OnCompleted(() => Task.Delay(TimeSpan.FromMinutes(5))); + await context.Response.WriteAsync("SlowOnCompleted"); + } } } diff --git a/src/Servers/IIS/IISIntegration/ref/Microsoft.AspNetCore.Server.IISIntegration.netcoreapp.cs b/src/Servers/IIS/IISIntegration/ref/Microsoft.AspNetCore.Server.IISIntegration.netcoreapp.cs index 9d45cf24cf..d8f4fce669 100644 --- a/src/Servers/IIS/IISIntegration/ref/Microsoft.AspNetCore.Server.IISIntegration.netcoreapp.cs +++ b/src/Servers/IIS/IISIntegration/ref/Microsoft.AspNetCore.Server.IISIntegration.netcoreapp.cs @@ -6,9 +6,9 @@ namespace Microsoft.AspNetCore.Builder public partial class IISOptions { public IISOptions() { } - public string AuthenticationDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool AutomaticAuthentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool ForwardClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AuthenticationDisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool AutomaticAuthentication { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool ForwardClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Hosting diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs index acfcaecc42..a25c4a0d5e 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs @@ -334,7 +334,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS if (DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) { - pool.SetAttributeValue("enable32BitAppOnWin64", "true");; + pool.SetAttributeValue("enable32BitAppOnWin64", "true"); } RunServerConfigActions(config, contentRoot); diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentParameterExtensions.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentParameterExtensions.cs index 90f76fd8c2..89b50d5450 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentParameterExtensions.cs +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeploymentParameterExtensions.cs @@ -27,6 +27,21 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS } public static void AddHttpsToServerConfig(this IISDeploymentParameters parameters) + { + parameters.AddServerConfigAction( + element => + { + element.Descendants("binding") + .Single() + .SetAttributeValue("protocol", "https"); + + element.Descendants("access") + .Single() + .SetAttributeValue("sslFlags", "None"); + }); + } + + public static void AddHttpsWithClientCertToServerConfig(this IISDeploymentParameters parameters) { parameters.AddServerConfigAction( element => diff --git a/src/Servers/IIS/build/testsite.props b/src/Servers/IIS/build/testsite.props index 066f50aca8..4ff733d387 100644 --- a/src/Servers/IIS/build/testsite.props +++ b/src/Servers/IIS/build/testsite.props @@ -32,7 +32,7 @@ <IISArguments>-h "$(IISAppHostConfig)"</IISArguments> <AncmInProcessRHPath>aspnetcorev2_inprocess.dll</AncmInProcessRHPath> - <!-- TODO: use LocalDotNetRoot instead to find dotnet.exe (see reporoot/Directory.Build.props). Requires a fix to https://github.com/aspnet/AspNetCore/issues/7196 --> + <!-- TODO: use LocalDotNetRoot instead to find dotnet.exe (see reporoot/Directory.Build.props). Requires a fix to https://github.com/dotnet/aspnetcore/issues/7196 --> <DotNetPath>$(RepoRoot).dotnet\dotnet.exe</DotNetPath> <DotNetPath Condition="'$(NativePlatform)' != 'x64'">$(RepoRoot).dotnet\$(NativePlatform)\dotnet.exe</DotNetPath> </PropertyGroup> diff --git a/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp.cs b/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp.cs index b9f222f076..5bd3bcd410 100644 --- a/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp.cs +++ b/src/Servers/Kestrel/Core/ref/Microsoft.AspNetCore.Server.Kestrel.Core.netcoreapp.cs @@ -34,16 +34,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel public partial class EndpointConfiguration { internal EndpointConfiguration() { } - public Microsoft.Extensions.Configuration.IConfigurationSection ConfigSection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Server.Kestrel.Https.HttpsConnectionAdapterOptions HttpsOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool IsHttps { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions ListenOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Configuration.IConfigurationSection ConfigSection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.Kestrel.Https.HttpsConnectionAdapterOptions HttpsOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool IsHttps { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions ListenOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class KestrelConfigurationLoader { internal KestrelConfigurationLoader() { } - public Microsoft.Extensions.Configuration.IConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.Configuration.IConfiguration Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions Options { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader AnyIPEndpoint(int port) { throw null; } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader AnyIPEndpoint(int port, System.Action<Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions> configure) { throw null; } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Endpoint(System.Net.IPAddress address, int port) { throw null; } @@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public sealed partial class BadHttpRequestException : System.IO.IOException { internal BadHttpRequestException() { } - public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class Http2Limits { @@ -77,6 +77,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public int MaxRequestHeaderFieldSize { get { throw null; } set { } } public int MaxStreamsPerConnection { get { throw null; } set { } } } + public partial class Http3Limits + { + public Http3Limits() { } + public int HeaderTableSize { get { throw null; } set { } } + public int MaxRequestHeaderFieldSize { get { throw null; } set { } } + } [System.FlagsAttribute] public enum HttpProtocols { @@ -84,11 +90,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core Http1 = 1, Http2 = 2, Http1AndHttp2 = 3, + Http3 = 4, + Http1AndHttp2AndHttp3 = 7, } public partial class KestrelServer : Microsoft.AspNetCore.Hosting.Server.IServer, System.IDisposable { - public KestrelServer(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions> options, Microsoft.AspNetCore.Connections.IConnectionListenerFactory transportFactory, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } - public Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public KestrelServer(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions> options, System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Connections.IConnectionListenerFactory> transportFactories, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } + public Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions Options { get { throw null; } } public void Dispose() { } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -99,7 +107,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public partial class KestrelServerLimits { public KestrelServerLimits() { } - public Microsoft.AspNetCore.Server.Kestrel.Core.Http2Limits Http2 { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.Server.Kestrel.Core.Http2Limits Http2 { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.Kestrel.Core.Http3Limits Http3 { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.TimeSpan KeepAliveTimeout { get { throw null; } set { } } public long? MaxConcurrentConnections { get { throw null; } set { } } public long? MaxConcurrentUpgradedConnections { get { throw null; } set { } } @@ -109,19 +118,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public int MaxRequestHeadersTotalSize { get { throw null; } set { } } public int MaxRequestLineSize { get { throw null; } set { } } public long? MaxResponseBufferSize { get { throw null; } set { } } - public Microsoft.AspNetCore.Server.Kestrel.Core.MinDataRate MinRequestBodyDataRate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Server.Kestrel.Core.MinDataRate MinResponseDataRate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Server.Kestrel.Core.MinDataRate MinRequestBodyDataRate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Server.Kestrel.Core.MinDataRate MinResponseDataRate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.TimeSpan RequestHeadersTimeout { get { throw null; } set { } } } public partial class KestrelServerOptions { public KestrelServerOptions() { } - public bool AddServerHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool AllowSynchronousIO { [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 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 bool AddServerHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool AllowSynchronousIO { [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 bool DisableStringReuse { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool EnableAltSvc { [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.KestrelConfigurationLoader Configure() { throw null; } public Microsoft.AspNetCore.Server.Kestrel.KestrelConfigurationLoader Configure(Microsoft.Extensions.Configuration.IConfiguration config) { throw null; } public void ConfigureEndpointDefaults(System.Action<Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions> configureOptions) { } @@ -145,8 +155,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public System.IServiceProvider ApplicationServices { get { throw null; } } public ulong FileHandle { get { throw null; } } public System.Net.IPEndPoint IPEndPoint { get { throw null; } } - public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions KestrelServerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols Protocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions KestrelServerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols Protocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string SocketPath { get { throw null; } } public Microsoft.AspNetCore.Connections.ConnectionDelegate Build() { throw null; } public override string ToString() { throw null; } @@ -155,8 +165,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core public partial class MinDataRate { public MinDataRate(double bytesPerSecond, System.TimeSpan gracePeriod) { } - public double BytesPerSecond { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.TimeSpan GracePeriod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public double BytesPerSecond { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.TimeSpan GracePeriod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } namespace Microsoft.AspNetCore.Server.Kestrel.Core.Features @@ -204,11 +214,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http Custom = (byte)9, None = (byte)255, } - public partial class HttpParser<TRequestHandler> : Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler> where TRequestHandler : Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpHeadersHandler, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpRequestLineHandler + public partial class HttpParser<TRequestHandler> where TRequestHandler : Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpHeadersHandler, Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpRequestLineHandler { public HttpParser() { } public HttpParser(bool showErrorDetails) { } - bool Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler>.ParseRequestLine(TRequestHandler handler, in System.Buffers.ReadOnlySequence<byte> buffer, out System.SequencePosition consumed, out System.SequencePosition examined) { throw null; } public bool ParseHeaders(TRequestHandler handler, ref System.Buffers.SequenceReader<byte> reader) { throw null; } public bool ParseRequestLine(TRequestHandler handler, in System.Buffers.ReadOnlySequence<byte> buffer, out System.SequencePosition consumed, out System.SequencePosition examined) { throw null; } } @@ -224,16 +233,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http Http10 = 0, Http11 = 1, Http2 = 2, + Http3 = 3, } public partial interface IHttpHeadersHandler { - 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 - { - bool ParseHeaders(TRequestHandler handler, ref System.Buffers.SequenceReader<byte> reader); - bool ParseRequestLine(TRequestHandler handler, in System.Buffers.ReadOnlySequence<byte> buffer, out System.SequencePosition consumed, out System.SequencePosition examined); + void OnHeader(System.ReadOnlySpan<byte> name, System.ReadOnlySpan<byte> value); + void OnHeadersComplete(bool endStream); } public partial interface IHttpRequestLineHandler { @@ -255,14 +260,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https public partial class HttpsConnectionAdapterOptions { public HttpsConnectionAdapterOptions() { } - public bool CheckCertificateRevocation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode ClientCertificateMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<System.Security.Cryptography.X509Certificates.X509Certificate2, System.Security.Cryptography.X509Certificates.X509Chain, System.Net.Security.SslPolicyErrors, bool> ClientCertificateValidation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool CheckCertificateRevocation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode ClientCertificateMode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<System.Security.Cryptography.X509Certificates.X509Certificate2, System.Security.Cryptography.X509Certificates.X509Chain, System.Net.Security.SslPolicyErrors, bool> ClientCertificateValidation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.TimeSpan HandshakeTimeout { get { throw null; } set { } } - public System.Action<Microsoft.AspNetCore.Connections.ConnectionContext, System.Net.Security.SslServerAuthenticationOptions> OnAuthenticate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Cryptography.X509Certificates.X509Certificate2 ServerCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<Microsoft.AspNetCore.Connections.ConnectionContext, string, System.Security.Cryptography.X509Certificates.X509Certificate2> ServerCertificateSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Security.Authentication.SslProtocols SslProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Action<Microsoft.AspNetCore.Connections.ConnectionContext, System.Net.Security.SslServerAuthenticationOptions> OnAuthenticate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 ServerCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<Microsoft.AspNetCore.Connections.ConnectionContext, string, System.Security.Cryptography.X509Certificates.X509Certificate2> ServerCertificateSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Authentication.SslProtocols SslProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public void AllowAnyClientCertificate() { } } } diff --git a/src/Servers/Kestrel/Core/src/BadHttpRequestException.cs b/src/Servers/Kestrel/Core/src/BadHttpRequestException.cs index 929a408778..16f7ab0fce 100644 --- a/src/Servers/Kestrel/Core/src/BadHttpRequestException.cs +++ b/src/Servers/Kestrel/Core/src/BadHttpRequestException.cs @@ -139,6 +139,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core BadHttpRequestException ex; switch (reason) { + case RequestRejectionReason.TlsOverHttpError: + ex = new BadHttpRequestException(CoreStrings.HttpParserTlsOverHttpError, StatusCodes.Status400BadRequest, reason); + break; case RequestRejectionReason.InvalidRequestLine: ex = new BadHttpRequestException(CoreStrings.FormatBadRequest_InvalidRequestLine_Detail(detail), StatusCodes.Status400BadRequest, reason); break; diff --git a/src/Servers/Kestrel/Core/src/CoreStrings.resx b/src/Servers/Kestrel/Core/src/CoreStrings.resx index cb3245b4fe..3a25467bcc 100644 --- a/src/Servers/Kestrel/Core/src/CoreStrings.resx +++ b/src/Servers/Kestrel/Core/src/CoreStrings.resx @@ -249,9 +249,6 @@ <data name="BindingToDefaultAddress" xml:space="preserve"> <value>No listening endpoints were configured. Binding to {address} by default.</value> </data> - <data name="ConfigureHttpsFromMethodCall" xml:space="preserve"> - <value>HTTPS endpoints can only be configured using {methodName}.</value> - </data> <data name="ConfigurePathBaseFromMethodCall" xml:space="preserve"> <value>A path base can only be configured using {methodName}.</value> </data> @@ -261,9 +258,6 @@ <data name="EndpointAlreadyInUse" xml:space="preserve"> <value>Failed to bind to address {endpoint}: address already in use.</value> </data> - <data name="InvalidUrl" xml:space="preserve"> - <value>Invalid URL: '{url}'.</value> - </data> <data name="NetworkInterfaceBindingFailed" xml:space="preserve"> <value>Unable to bind to {address} on the {interfaceName} interface: '{error}'.</value> </data> @@ -288,9 +282,6 @@ <data name="ParameterReadOnlyAfterResponseStarted" xml:space="preserve"> <value>{name} cannot be set because the response has already started.</value> </data> - <data name="RequestProcessingAborted" xml:space="preserve"> - <value>Request processing didn't complete within the shutdown timeout.</value> - </data> <data name="TooFewBytesWritten" xml:space="preserve"> <value>Response Content-Length mismatch: too few bytes written ({written} of {expected}).</value> </data> @@ -330,9 +321,6 @@ <data name="PositiveTimeSpanRequired" xml:space="preserve"> <value>Value must be a positive TimeSpan.</value> </data> - <data name="NonNegativeTimeSpanRequired" xml:space="preserve"> - <value>Value must be a non-negative TimeSpan.</value> - </data> <data name="MinimumGracePeriodRequired" xml:space="preserve"> <value>The request body rate enforcement grace period must be greater than {heartbeatInterval} second.</value> </data> @@ -357,30 +345,6 @@ <data name="EndPointHttp2NotNegotiated" xml:space="preserve"> <value>HTTP/2 over TLS was not negotiated on an HTTP/2-only endpoint.</value> </data> - <data name="HPackErrorDynamicTableSizeUpdateTooLarge" xml:space="preserve"> - <value>A dynamic table size of {size} octets is greater than the configured maximum size of {maxSize} octets.</value> - </data> - <data name="HPackErrorIndexOutOfRange" xml:space="preserve"> - <value>Index {index} is outside the bounds of the header field table.</value> - </data> - <data name="HPackHuffmanErrorIncomplete" xml:space="preserve"> - <value>Input data could not be fully decoded.</value> - </data> - <data name="HPackHuffmanErrorEOS" xml:space="preserve"> - <value>Input data contains the EOS symbol.</value> - </data> - <data name="HPackHuffmanErrorDestinationTooSmall" xml:space="preserve"> - <value>The destination buffer is not large enough to store the decoded data.</value> - </data> - <data name="HPackHuffmanError" xml:space="preserve"> - <value>Huffman decoding error.</value> - </data> - <data name="HPackStringLengthTooLarge" xml:space="preserve"> - <value>Decoded string length of {length} octets is greater than the configured maximum length of {maxStringLength} octets.</value> - </data> - <data name="HPackErrorIncompleteHeaderBlock" xml:space="preserve"> - <value>The header block was incomplete and could not be fully decoded.</value> - </data> <data name="Http2ErrorStreamIdEven" xml:space="preserve"> <value>The client sent a {frameType} frame with even stream ID {streamId}.</value> </data> @@ -459,9 +423,6 @@ <data name="Http2ErrorConnectionSpecificHeaderField" xml:space="preserve"> <value>Request headers contain connection-specific header field.</value> </data> - <data name="UnableToConfigureHttpsBindings" xml:space="preserve"> - <value>Unable to configure default https bindings because no IDefaultHttpsProvider service was provided.</value> - </data> <data name="AuthenticationFailed" xml:space="preserve"> <value>Failed to authenticate HTTPS connection.</value> </data> @@ -471,9 +432,6 @@ <data name="InvalidServerCertificateEku" xml:space="preserve"> <value>Certificate {thumbprint} cannot be used as an SSL server certificate. It has an Extended Key Usage extension but the usages do not include Server Authentication (OID 1.3.6.1.5.5.7.3.1).</value> </data> - <data name="PositiveTimeSpanRequired1" xml:space="preserve"> - <value>Value must be a positive TimeSpan.</value> - </data> <data name="ServerCertificateRequired" xml:space="preserve"> <value>The server certificate parameter is required.</value> </data> @@ -575,30 +533,12 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l <data name="ArgumentOutOfRange" xml:space="preserve"> <value>A value between {min} and {max} is required.</value> </data> - <data name="HPackErrorDynamicTableSizeUpdateNotAtBeginningOfHeaderBlock" xml:space="preserve"> - <value>Dynamic tables size update did not occur at the beginning of the first header block.</value> - </data> - <data name="HPackErrorNotEnoughBuffer" xml:space="preserve"> - <value>The given buffer was too small to encode any headers.</value> - </data> - <data name="HPackErrorIntegerTooBig" xml:space="preserve"> - <value>The decoded integer exceeds the maximum value of Int32.MaxValue.</value> - </data> <data name="ConnectionAbortedByClient" xml:space="preserve"> <value>The client closed the connection.</value> </data> <data name="Http2ErrorStreamAborted" xml:space="preserve"> <value>A frame of type {frameType} was received after stream {streamId} was reset or aborted.</value> </data> - <data name="ProtocolSelectionFailed" xml:space="preserve"> - <value>HTTP protocol selection failed.</value> - </data> - <data name="ServerShutdownDuringConnectionInitialization" xml:space="preserve"> - <value>Server shutdown started during connection initialization.</value> - </data> - <data name="StartAsyncBeforeGetMemory" xml:space="preserve"> - <value>Cannot call GetMemory() until response has started. Call HttpResponse.StartAsync() before calling GetMemory().</value> - </data> <data name="Http2MinDataRateNotSupported" xml:space="preserve"> <value>This feature is not supported for HTTP/2 requests except to disable it entirely by setting the rate to null.</value> </data> @@ -617,7 +557,28 @@ For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?l <data name="Http2TellClientToCalmDown" xml:space="preserve"> <value>A new stream was refused because this connection has too many streams that haven't finished processing. This may happen if many streams are aborted but not yet cleaned up.</value> </data> + <data name="HttpParserTlsOverHttpError" xml:space="preserve"> + <value>Detected a TLS handshake to an endpoint that does not have TLS enabled.</value> + </data> <data name="BadDeveloperCertificateState" xml:space="preserve"> <value>The ASP.NET Core developer certificate is in an invalid state. To fix this issue, run the following commands 'dotnet dev-certs https --clean' and 'dotnet dev-certs https' to remove all existing ASP.NET Core development certificates and create a new untrusted developer certificate. On macOS or Windows, use 'dotnet dev-certs https --trust' to trust the new certificate.</value> </data> -</root> + <data name="QPackErrorIndexOutOfRange" xml:space="preserve"> + <value>Index {index} is outside the bounds of the header field table.</value> + </data> + <data name="QPackErrorIntegerTooBig" xml:space="preserve"> + <value>The decoded integer exceeds the maximum value of Int32.MaxValue.</value> + </data> + <data name="QPackHuffmanError" xml:space="preserve"> + <value>Huffman decoding error.</value> + </data> + <data name="QPackStringLengthTooLarge" xml:space="preserve"> + <value>Decoded string length of {length} octets is greater than the configured maximum length of {maxStringLength} octets.</value> + </data> + <data name="QuicTransportNotFound" xml:space="preserve"> + <value>Quic transport not found when using HTTP/3.</value> + </data> + <data name="TransportNotFound" xml:space="preserve"> + <value>Unable to resolve service for type 'Microsoft.AspNetCore.Connections.IConnectionListenerFactory' while attempting to activate 'Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer'.</value> + </data> +</root> \ No newline at end of file diff --git a/src/Servers/Kestrel/Core/src/Http3Limits.cs b/src/Servers/Kestrel/Core/src/Http3Limits.cs new file mode 100644 index 0000000000..fa82ede8c3 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Http3Limits.cs @@ -0,0 +1,53 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core +{ + public class Http3Limits + { + private int _headerTableSize = 4096; + private int _maxRequestHeaderFieldSize = 8192; + + /// <summary> + /// Limits the size of the header compression table, in octets, the HPACK decoder on the server can use. + /// <para> + /// Value must be greater than 0, defaults to 4096 + /// </para> + /// </summary> + public int HeaderTableSize + { + get => _headerTableSize; + set + { + if (value <= 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, CoreStrings.GreaterThanZeroRequired); + } + + _headerTableSize = value; + } + } + + /// <summary> + /// Indicates the size of the maximum allowed size of a request header field sequence. This limit applies to both name and value sequences in their compressed and uncompressed representations. + /// <para> + /// Value must be greater than 0, defaults to 8192 + /// </para> + /// </summary> + public int MaxRequestHeaderFieldSize + { + get => _maxRequestHeaderFieldSize; + set + { + if (value <= 0) + { + throw new ArgumentOutOfRangeException(nameof(value), value, CoreStrings.GreaterThanZeroRequired); + } + + _maxRequestHeaderFieldSize = value; + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/HttpProtocols.cs b/src/Servers/Kestrel/Core/src/HttpProtocols.cs index 09524bf156..294ae6ae69 100644 --- a/src/Servers/Kestrel/Core/src/HttpProtocols.cs +++ b/src/Servers/Kestrel/Core/src/HttpProtocols.cs @@ -12,5 +12,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core Http1 = 0x1, Http2 = 0x2, Http1AndHttp2 = Http1 | Http2, + Http3 = 0x4, + Http1AndHttp2AndHttp3 = Http1 | Http2 | Http3 } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ChunkWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ChunkWriter.cs index 75186e8ad6..8d64e7b762 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ChunkWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ChunkWriter.cs @@ -6,12 +6,14 @@ using System.Buffers; using System.IO.Pipelines; using System.Text; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal static class ChunkWriter { - private static readonly byte[] _hex = Encoding.ASCII.GetBytes("0123456789abcdef"); + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + private static ReadOnlySpan<byte> Hex => new byte[16] { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f' }; public static int BeginChunkBytes(int dataCount, Span<byte> span) { @@ -28,7 +30,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http count = (total >> 2) + 3; var offset = 0; - ref var startHex = ref _hex[0]; + ref var startHex = ref MemoryMarshal.GetReference(Hex); for (shift = total; shift >= 0; shift -= 4) { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/DateHeaderValueManager.cs b/src/Servers/Kestrel/Core/src/Internal/Http/DateHeaderValueManager.cs index 371033b330..85b9ad8b61 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/DateHeaderValueManager.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/DateHeaderValueManager.cs @@ -14,7 +14,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http /// </summary> internal class DateHeaderValueManager : IHeartbeatHandler { - private static readonly byte[] _datePreambleBytes = Encoding.ASCII.GetBytes("\r\nDate: "); + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + private static ReadOnlySpan<byte> DatePreambleBytes => new byte[8] { (byte)'\r', (byte)'\n', (byte)'D', (byte)'a', (byte)'t', (byte)'e', (byte)':', (byte)' ' }; private DateHeaderValues _dateValues; @@ -38,9 +39,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private void SetDateValues(DateTimeOffset value) { var dateValue = HeaderUtilities.FormatDate(value); - var dateBytes = new byte[_datePreambleBytes.Length + dateValue.Length]; - Buffer.BlockCopy(_datePreambleBytes, 0, dateBytes, 0, _datePreambleBytes.Length); - Encoding.ASCII.GetBytes(dateValue, 0, dateValue.Length, dateBytes, _datePreambleBytes.Length); + var dateBytes = new byte[DatePreambleBytes.Length + dateValue.Length]; + DatePreambleBytes.CopyTo(dateBytes); + Encoding.ASCII.GetBytes(dateValue, dateBytes.AsSpan(DatePreambleBytes.Length)); var dateValues = new DateHeaderValues { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs index b4c67c13a3..f76ab52a8f 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ParsingHandler.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net.Http; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { @@ -22,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http Trailers = trailers; } - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { if (Trailers) { @@ -34,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } - public void OnHeadersComplete() + public void OnHeadersComplete(bool endStream) { if (Trailers) { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs index e626a19d9c..402809d818 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -5768,7 +5768,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public unsafe void Append(Span<byte> name, Span<byte> value) + public unsafe void Append(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { ref byte nameStart = ref MemoryMarshal.GetReference(name); ref StringValues values = ref Unsafe.AsRef<StringValues>(null); @@ -6659,14 +6659,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { private static ReadOnlySpan<byte> HeaderBytes => new byte[] { - 13,10,67,97,99,104,101,45,67,111,110,116,114,111,108,58,32,13,10,67,111,110,110,101,99,116,105,111,110,58,32,13,10,68,97,116,101,58,32,13,10,75,101,101,112,45,65,108,105,118,101,58,32,13,10,80,114,97,103,109,97,58,32,13,10,84,114,97,105,108,101,114,58,32,13,10,84,114,97,110,115,102,101,114,45,69,110,99,111,100,105,110,103,58,32,13,10,85,112,103,114,97,100,101,58,32,13,10,86,105,97,58,32,13,10,87,97,114,110,105,110,103,58,32,13,10,65,108,108,111,119,58,32,13,10,67,111,110,116,101,110,116,45,84,121,112,101,58,32,13,10,67,111,110,116,101,110,116,45,69,110,99,111,100,105,110,103,58,32,13,10,67,111,110,116,101,110,116,45,76,97,110,103,117,97,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,111,99,97,116,105,111,110,58,32,13,10,67,111,110,116,101,110,116,45,77,68,53,58,32,13,10,67,111,110,116,101,110,116,45,82,97,110,103,101,58,32,13,10,69,120,112,105,114,101,115,58,32,13,10,76,97,115,116,45,77,111,100,105,102,105,101,100,58,32,13,10,65,99,99,101,112,116,45,82,97,110,103,101,115,58,32,13,10,65,103,101,58,32,13,10,69,84,97,103,58,32,13,10,76,111,99,97,116,105,111,110,58,32,13,10,80,114,111,120,121,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,82,101,116,114,121,45,65,102,116,101,114,58,32,13,10,83,101,114,118,101,114,58,32,13,10,83,101,116,45,67,111,111,107,105,101,58,32,13,10,86,97,114,121,58,32,13,10,87,87,87,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,67,114,101,100,101,110,116,105,97,108,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,77,101,116,104,111,100,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,79,114,105,103,105,110,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,69,120,112,111,115,101,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,77,97,120,45,65,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,101,110,103,116,104,58,32, + 13,10,67,97,99,104,101,45,67,111,110,116,114,111,108,58,32,13,10,67,111,110,110,101,99,116,105,111,110,58,32,13,10,68,97,116,101,58,32,13,10,75,101,101,112,45,65,108,105,118,101,58,32,13,10,80,114,97,103,109,97,58,32,13,10,84,114,97,105,108,101,114,58,32,13,10,84,114,97,110,115,102,101,114,45,69,110,99,111,100,105,110,103,58,32,13,10,85,112,103,114,97,100,101,58,32,13,10,86,105,97,58,32,13,10,87,97,114,110,105,110,103,58,32,13,10,65,108,108,111,119,58,32,13,10,67,111,110,116,101,110,116,45,84,121,112,101,58,32,13,10,67,111,110,116,101,110,116,45,69,110,99,111,100,105,110,103,58,32,13,10,67,111,110,116,101,110,116,45,76,97,110,103,117,97,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,111,99,97,116,105,111,110,58,32,13,10,67,111,110,116,101,110,116,45,77,68,53,58,32,13,10,67,111,110,116,101,110,116,45,82,97,110,103,101,58,32,13,10,69,120,112,105,114,101,115,58,32,13,10,76,97,115,116,45,77,111,100,105,102,105,101,100,58,32,13,10,65,99,99,101,112,116,45,82,97,110,103,101,115,58,32,13,10,65,103,101,58,32,13,10,65,108,116,45,83,118,99,58,32,13,10,69,84,97,103,58,32,13,10,76,111,99,97,116,105,111,110,58,32,13,10,80,114,111,120,121,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,82,101,116,114,121,45,65,102,116,101,114,58,32,13,10,83,101,114,118,101,114,58,32,13,10,83,101,116,45,67,111,111,107,105,101,58,32,13,10,86,97,114,121,58,32,13,10,87,87,87,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,67,114,101,100,101,110,116,105,97,108,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,77,101,116,104,111,100,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,79,114,105,103,105,110,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,69,120,112,111,115,101,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,77,97,120,45,65,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,101,110,103,116,104,58,32, }; private HeaderReferences _headers; public bool HasConnection => (_bits & 0x2L) != 0; public bool HasDate => (_bits & 0x4L) != 0; public bool HasTransferEncoding => (_bits & 0x40L) != 0; - public bool HasServer => (_bits & 0x2000000L) != 0; + public bool HasServer => (_bits & 0x4000000L) != 0; public StringValues HeaderCacheControl @@ -7029,12 +7029,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _headers._Age = value; } } - public StringValues HeaderETag + public StringValues HeaderAltSvc { get { StringValues value = default; if ((_bits & 0x200000L) != 0) + { + value = _headers._AltSvc; + } + return value; + } + set + { + _bits |= 0x200000L; + _headers._AltSvc = value; + } + } + public StringValues HeaderETag + { + get + { + StringValues value = default; + if ((_bits & 0x400000L) != 0) { value = _headers._ETag; } @@ -7042,7 +7059,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x200000L; + _bits |= 0x400000L; _headers._ETag = value; } } @@ -7051,7 +7068,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x400000L) != 0) + if ((_bits & 0x800000L) != 0) { value = _headers._Location; } @@ -7059,7 +7076,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x400000L; + _bits |= 0x800000L; _headers._Location = value; } } @@ -7068,7 +7085,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x800000L) != 0) + if ((_bits & 0x1000000L) != 0) { value = _headers._ProxyAuthenticate; } @@ -7076,7 +7093,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x800000L; + _bits |= 0x1000000L; _headers._ProxyAuthenticate = value; } } @@ -7085,7 +7102,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x1000000L) != 0) + if ((_bits & 0x2000000L) != 0) { value = _headers._RetryAfter; } @@ -7093,7 +7110,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x1000000L; + _bits |= 0x2000000L; _headers._RetryAfter = value; } } @@ -7102,7 +7119,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x2000000L) != 0) + if ((_bits & 0x4000000L) != 0) { value = _headers._Server; } @@ -7110,7 +7127,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x2000000L; + _bits |= 0x4000000L; _headers._Server = value; _headers._rawServer = null; } @@ -7120,7 +7137,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { value = _headers._SetCookie; } @@ -7128,7 +7145,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._SetCookie = value; } } @@ -7137,7 +7154,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { value = _headers._Vary; } @@ -7145,7 +7162,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Vary = value; } } @@ -7154,7 +7171,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { value = _headers._WWWAuthenticate; } @@ -7162,7 +7179,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._WWWAuthenticate = value; } } @@ -7171,7 +7188,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { value = _headers._AccessControlAllowCredentials; } @@ -7179,7 +7196,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._AccessControlAllowCredentials = value; } } @@ -7188,7 +7205,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { value = _headers._AccessControlAllowHeaders; } @@ -7196,7 +7213,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._AccessControlAllowHeaders = value; } } @@ -7205,7 +7222,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { value = _headers._AccessControlAllowMethods; } @@ -7213,7 +7230,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowMethods = value; } } @@ -7222,7 +7239,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { value = _headers._AccessControlAllowOrigin; } @@ -7230,7 +7247,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowOrigin = value; } } @@ -7239,7 +7256,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { value = _headers._AccessControlExposeHeaders; } @@ -7247,7 +7264,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlExposeHeaders = value; } } @@ -7256,7 +7273,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { StringValues value = default; - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { value = _headers._AccessControlMaxAge; } @@ -7264,7 +7281,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } set { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlMaxAge = value; } } @@ -7305,7 +7322,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } public void SetRawServer(StringValues value, byte[] raw) { - _bits |= 0x2000000L; + _bits |= 0x4000000L; _headers._Server = value; _headers._rawServer = raw; } @@ -7373,7 +7390,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.ETag, key)) { - if ((_bits & 0x200000L) != 0) + if ((_bits & 0x400000L) != 0) { value = _headers._ETag; return true; @@ -7382,7 +7399,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.Vary, key)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { value = _headers._Vary; return true; @@ -7401,7 +7418,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.ETag.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000L) != 0) + if ((_bits & 0x400000L) != 0) { value = _headers._ETag; return true; @@ -7410,7 +7427,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { value = _headers._Vary; return true; @@ -7446,7 +7463,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.Server, key)) { - if ((_bits & 0x2000000L) != 0) + if ((_bits & 0x4000000L) != 0) { value = _headers._Server; return true; @@ -7465,7 +7482,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x2000000L) != 0) + if ((_bits & 0x4000000L) != 0) { value = _headers._Server; return true; @@ -7521,6 +7538,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if (ReferenceEquals(HeaderNames.AltSvc, key)) + { + if ((_bits & 0x200000L) != 0) + { + value = _headers._AltSvc; + return true; + } + return false; + } if (HeaderNames.Trailer.Equals(key, StringComparison.OrdinalIgnoreCase)) { @@ -7558,13 +7584,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if (HeaderNames.AltSvc.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x200000L) != 0) + { + value = _headers._AltSvc; + return true; + } + return false; + } break; } case 8: { if (ReferenceEquals(HeaderNames.Location, key)) { - if ((_bits & 0x400000L) != 0) + if ((_bits & 0x800000L) != 0) { value = _headers._Location; return true; @@ -7574,7 +7609,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Location.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000L) != 0) + if ((_bits & 0x800000L) != 0) { value = _headers._Location; return true; @@ -7605,7 +7640,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { value = _headers._SetCookie; return true; @@ -7633,7 +7668,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { value = _headers._SetCookie; return true; @@ -7655,7 +7690,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - if ((_bits & 0x1000000L) != 0) + if ((_bits & 0x2000000L) != 0) { value = _headers._RetryAfter; return true; @@ -7674,7 +7709,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x1000000L) != 0) + if ((_bits & 0x2000000L) != 0) { value = _headers._RetryAfter; return true; @@ -7837,7 +7872,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { value = _headers._WWWAuthenticate; return true; @@ -7874,7 +7909,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { value = _headers._WWWAuthenticate; return true; @@ -7910,7 +7945,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.ProxyAuthenticate, key)) { - if ((_bits & 0x800000L) != 0) + if ((_bits & 0x1000000L) != 0) { value = _headers._ProxyAuthenticate; return true; @@ -7920,7 +7955,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.ProxyAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x800000L) != 0) + if ((_bits & 0x1000000L) != 0) { value = _headers._ProxyAuthenticate; return true; @@ -7933,7 +7968,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { value = _headers._AccessControlMaxAge; return true; @@ -7943,7 +7978,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { value = _headers._AccessControlMaxAge; return true; @@ -7956,7 +7991,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { value = _headers._AccessControlAllowOrigin; return true; @@ -7966,7 +8001,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { value = _headers._AccessControlAllowOrigin; return true; @@ -7979,7 +8014,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { value = _headers._AccessControlAllowHeaders; return true; @@ -7988,7 +8023,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { value = _headers._AccessControlAllowMethods; return true; @@ -7998,7 +8033,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { value = _headers._AccessControlAllowHeaders; return true; @@ -8007,7 +8042,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { value = _headers._AccessControlAllowMethods; return true; @@ -8020,7 +8055,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { value = _headers._AccessControlExposeHeaders; return true; @@ -8030,7 +8065,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { value = _headers._AccessControlExposeHeaders; return true; @@ -8043,7 +8078,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { value = _headers._AccessControlAllowCredentials; return true; @@ -8053,7 +8088,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { value = _headers._AccessControlAllowCredentials; return true; @@ -8112,13 +8147,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.ETag, key)) { - _bits |= 0x200000L; + _bits |= 0x400000L; _headers._ETag = value; return; } if (ReferenceEquals(HeaderNames.Vary, key)) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Vary = value; return; } @@ -8132,13 +8167,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.ETag.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x200000L; + _bits |= 0x400000L; _headers._ETag = value; return; } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Vary = value; return; } @@ -8165,7 +8200,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.Server, key)) { - _bits |= 0x2000000L; + _bits |= 0x4000000L; _headers._Server = value; _headers._rawServer = null; return; @@ -8179,7 +8214,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x2000000L; + _bits |= 0x4000000L; _headers._Server = value; _headers._rawServer = null; return; @@ -8218,6 +8253,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _headers._Expires = value; return; } + if (ReferenceEquals(HeaderNames.AltSvc, key)) + { + _bits |= 0x200000L; + _headers._AltSvc = value; + return; + } if (HeaderNames.Trailer.Equals(key, StringComparison.OrdinalIgnoreCase)) { @@ -8243,20 +8284,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _headers._Expires = value; return; } + if (HeaderNames.AltSvc.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + _bits |= 0x200000L; + _headers._AltSvc = value; + return; + } break; } case 8: { if (ReferenceEquals(HeaderNames.Location, key)) { - _bits |= 0x400000L; + _bits |= 0x800000L; _headers._Location = value; return; } if (HeaderNames.Location.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x400000L; + _bits |= 0x800000L; _headers._Location = value; return; } @@ -8279,7 +8326,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._SetCookie = value; return; } @@ -8299,7 +8346,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._SetCookie = value; return; } @@ -8315,7 +8362,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - _bits |= 0x1000000L; + _bits |= 0x2000000L; _headers._RetryAfter = value; return; } @@ -8328,7 +8375,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x1000000L; + _bits |= 0x2000000L; _headers._RetryAfter = value; return; } @@ -8441,7 +8488,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._WWWAuthenticate = value; return; } @@ -8466,7 +8513,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._WWWAuthenticate = value; return; } @@ -8495,14 +8542,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.ProxyAuthenticate, key)) { - _bits |= 0x800000L; + _bits |= 0x1000000L; _headers._ProxyAuthenticate = value; return; } if (HeaderNames.ProxyAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x800000L; + _bits |= 0x1000000L; _headers._ProxyAuthenticate = value; return; } @@ -8512,14 +8559,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlMaxAge = value; return; } if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlMaxAge = value; return; } @@ -8529,14 +8576,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowOrigin = value; return; } if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowOrigin = value; return; } @@ -8546,26 +8593,26 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._AccessControlAllowHeaders = value; return; } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowMethods = value; return; } if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._AccessControlAllowHeaders = value; return; } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowMethods = value; return; } @@ -8575,14 +8622,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlExposeHeaders = value; return; } if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlExposeHeaders = value; return; } @@ -8592,14 +8639,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._AccessControlAllowCredentials = value; return; } if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._AccessControlAllowCredentials = value; return; } @@ -8675,9 +8722,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.ETag, key)) { - if ((_bits & 0x200000L) == 0) + if ((_bits & 0x400000L) == 0) { - _bits |= 0x200000L; + _bits |= 0x400000L; _headers._ETag = value; return true; } @@ -8685,9 +8732,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.Vary, key)) { - if ((_bits & 0x8000000L) == 0) + if ((_bits & 0x10000000L) == 0) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Vary = value; return true; } @@ -8707,9 +8754,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.ETag.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000L) == 0) + if ((_bits & 0x400000L) == 0) { - _bits |= 0x200000L; + _bits |= 0x400000L; _headers._ETag = value; return true; } @@ -8717,9 +8764,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000000L) == 0) + if ((_bits & 0x10000000L) == 0) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Vary = value; return true; } @@ -8756,9 +8803,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.Server, key)) { - if ((_bits & 0x2000000L) == 0) + if ((_bits & 0x4000000L) == 0) { - _bits |= 0x2000000L; + _bits |= 0x4000000L; _headers._Server = value; _headers._rawServer = null; return true; @@ -8778,9 +8825,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x2000000L) == 0) + if ((_bits & 0x4000000L) == 0) { - _bits |= 0x2000000L; + _bits |= 0x4000000L; _headers._Server = value; _headers._rawServer = null; return true; @@ -8841,6 +8888,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if (ReferenceEquals(HeaderNames.AltSvc, key)) + { + if ((_bits & 0x200000L) == 0) + { + _bits |= 0x200000L; + _headers._AltSvc = value; + return true; + } + return false; + } if (HeaderNames.Trailer.Equals(key, StringComparison.OrdinalIgnoreCase)) { @@ -8882,15 +8939,25 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if (HeaderNames.AltSvc.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x200000L) == 0) + { + _bits |= 0x200000L; + _headers._AltSvc = value; + return true; + } + return false; + } break; } case 8: { if (ReferenceEquals(HeaderNames.Location, key)) { - if ((_bits & 0x400000L) == 0) + if ((_bits & 0x800000L) == 0) { - _bits |= 0x400000L; + _bits |= 0x800000L; _headers._Location = value; return true; } @@ -8899,9 +8966,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Location.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000L) == 0) + if ((_bits & 0x800000L) == 0) { - _bits |= 0x400000L; + _bits |= 0x800000L; _headers._Location = value; return true; } @@ -8934,9 +9001,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - if ((_bits & 0x4000000L) == 0) + if ((_bits & 0x8000000L) == 0) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._SetCookie = value; return true; } @@ -8966,9 +9033,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x4000000L) == 0) + if ((_bits & 0x8000000L) == 0) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._SetCookie = value; return true; } @@ -8990,9 +9057,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - if ((_bits & 0x1000000L) == 0) + if ((_bits & 0x2000000L) == 0) { - _bits |= 0x1000000L; + _bits |= 0x2000000L; _headers._RetryAfter = value; return true; } @@ -9011,9 +9078,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x1000000L) == 0) + if ((_bits & 0x2000000L) == 0) { - _bits |= 0x1000000L; + _bits |= 0x2000000L; _headers._RetryAfter = value; return true; } @@ -9188,9 +9255,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - if ((_bits & 0x10000000L) == 0) + if ((_bits & 0x20000000L) == 0) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._WWWAuthenticate = value; return true; } @@ -9229,9 +9296,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000L) == 0) + if ((_bits & 0x20000000L) == 0) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._WWWAuthenticate = value; return true; } @@ -9270,9 +9337,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.ProxyAuthenticate, key)) { - if ((_bits & 0x800000L) == 0) + if ((_bits & 0x1000000L) == 0) { - _bits |= 0x800000L; + _bits |= 0x1000000L; _headers._ProxyAuthenticate = value; return true; } @@ -9281,9 +9348,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.ProxyAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x800000L) == 0) + if ((_bits & 0x1000000L) == 0) { - _bits |= 0x800000L; + _bits |= 0x1000000L; _headers._ProxyAuthenticate = value; return true; } @@ -9295,9 +9362,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - if ((_bits & 0x400000000L) == 0) + if ((_bits & 0x800000000L) == 0) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlMaxAge = value; return true; } @@ -9306,9 +9373,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000000L) == 0) + if ((_bits & 0x800000000L) == 0) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlMaxAge = value; return true; } @@ -9320,9 +9387,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - if ((_bits & 0x100000000L) == 0) + if ((_bits & 0x200000000L) == 0) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowOrigin = value; return true; } @@ -9331,9 +9398,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x100000000L) == 0) + if ((_bits & 0x200000000L) == 0) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowOrigin = value; return true; } @@ -9345,9 +9412,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - if ((_bits & 0x40000000L) == 0) + if ((_bits & 0x80000000L) == 0) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._AccessControlAllowHeaders = value; return true; } @@ -9355,9 +9422,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - if ((_bits & 0x80000000L) == 0) + if ((_bits & 0x100000000L) == 0) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowMethods = value; return true; } @@ -9366,9 +9433,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000L) == 0) + if ((_bits & 0x80000000L) == 0) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._AccessControlAllowHeaders = value; return true; } @@ -9376,9 +9443,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x80000000L) == 0) + if ((_bits & 0x100000000L) == 0) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowMethods = value; return true; } @@ -9390,9 +9457,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - if ((_bits & 0x200000000L) == 0) + if ((_bits & 0x400000000L) == 0) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlExposeHeaders = value; return true; } @@ -9401,9 +9468,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000000L) == 0) + if ((_bits & 0x400000000L) == 0) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlExposeHeaders = value; return true; } @@ -9415,9 +9482,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - if ((_bits & 0x20000000L) == 0) + if ((_bits & 0x40000000L) == 0) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._AccessControlAllowCredentials = value; return true; } @@ -9426,9 +9493,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000L) == 0) + if ((_bits & 0x40000000L) == 0) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._AccessControlAllowCredentials = value; return true; } @@ -9505,9 +9572,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.ETag, key)) { - if ((_bits & 0x200000L) != 0) + if ((_bits & 0x400000L) != 0) { - _bits &= ~0x200000L; + _bits &= ~0x400000L; _headers._ETag = default(StringValues); return true; } @@ -9515,9 +9582,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.Vary, key)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { - _bits &= ~0x8000000L; + _bits &= ~0x10000000L; _headers._Vary = default(StringValues); return true; } @@ -9537,9 +9604,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.ETag.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000L) != 0) + if ((_bits & 0x400000L) != 0) { - _bits &= ~0x200000L; + _bits &= ~0x400000L; _headers._ETag = default(StringValues); return true; } @@ -9547,9 +9614,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { - _bits &= ~0x8000000L; + _bits &= ~0x10000000L; _headers._Vary = default(StringValues); return true; } @@ -9586,9 +9653,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.Server, key)) { - if ((_bits & 0x2000000L) != 0) + if ((_bits & 0x4000000L) != 0) { - _bits &= ~0x2000000L; + _bits &= ~0x4000000L; _headers._Server = default(StringValues); _headers._rawServer = null; return true; @@ -9608,9 +9675,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x2000000L) != 0) + if ((_bits & 0x4000000L) != 0) { - _bits &= ~0x2000000L; + _bits &= ~0x4000000L; _headers._Server = default(StringValues); _headers._rawServer = null; return true; @@ -9671,6 +9738,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if (ReferenceEquals(HeaderNames.AltSvc, key)) + { + if ((_bits & 0x200000L) != 0) + { + _bits &= ~0x200000L; + _headers._AltSvc = default(StringValues); + return true; + } + return false; + } if (HeaderNames.Trailer.Equals(key, StringComparison.OrdinalIgnoreCase)) { @@ -9712,15 +9789,25 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } return false; } + if (HeaderNames.AltSvc.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x200000L) != 0) + { + _bits &= ~0x200000L; + _headers._AltSvc = default(StringValues); + return true; + } + return false; + } break; } case 8: { if (ReferenceEquals(HeaderNames.Location, key)) { - if ((_bits & 0x400000L) != 0) + if ((_bits & 0x800000L) != 0) { - _bits &= ~0x400000L; + _bits &= ~0x800000L; _headers._Location = default(StringValues); return true; } @@ -9729,9 +9816,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.Location.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000L) != 0) + if ((_bits & 0x800000L) != 0) { - _bits &= ~0x400000L; + _bits &= ~0x800000L; _headers._Location = default(StringValues); return true; } @@ -9764,9 +9851,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { - _bits &= ~0x4000000L; + _bits &= ~0x8000000L; _headers._SetCookie = default(StringValues); return true; } @@ -9796,9 +9883,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { - _bits &= ~0x4000000L; + _bits &= ~0x8000000L; _headers._SetCookie = default(StringValues); return true; } @@ -9820,9 +9907,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - if ((_bits & 0x1000000L) != 0) + if ((_bits & 0x2000000L) != 0) { - _bits &= ~0x1000000L; + _bits &= ~0x2000000L; _headers._RetryAfter = default(StringValues); return true; } @@ -9841,9 +9928,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x1000000L) != 0) + if ((_bits & 0x2000000L) != 0) { - _bits &= ~0x1000000L; + _bits &= ~0x2000000L; _headers._RetryAfter = default(StringValues); return true; } @@ -10018,9 +10105,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { - _bits &= ~0x10000000L; + _bits &= ~0x20000000L; _headers._WWWAuthenticate = default(StringValues); return true; } @@ -10059,9 +10146,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { - _bits &= ~0x10000000L; + _bits &= ~0x20000000L; _headers._WWWAuthenticate = default(StringValues); return true; } @@ -10100,9 +10187,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.ProxyAuthenticate, key)) { - if ((_bits & 0x800000L) != 0) + if ((_bits & 0x1000000L) != 0) { - _bits &= ~0x800000L; + _bits &= ~0x1000000L; _headers._ProxyAuthenticate = default(StringValues); return true; } @@ -10111,9 +10198,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.ProxyAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x800000L) != 0) + if ((_bits & 0x1000000L) != 0) { - _bits &= ~0x800000L; + _bits &= ~0x1000000L; _headers._ProxyAuthenticate = default(StringValues); return true; } @@ -10125,9 +10212,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { - _bits &= ~0x400000000L; + _bits &= ~0x800000000L; _headers._AccessControlMaxAge = default(StringValues); return true; } @@ -10136,9 +10223,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { - _bits &= ~0x400000000L; + _bits &= ~0x800000000L; _headers._AccessControlMaxAge = default(StringValues); return true; } @@ -10150,9 +10237,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { - _bits &= ~0x100000000L; + _bits &= ~0x200000000L; _headers._AccessControlAllowOrigin = default(StringValues); return true; } @@ -10161,9 +10248,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { - _bits &= ~0x100000000L; + _bits &= ~0x200000000L; _headers._AccessControlAllowOrigin = default(StringValues); return true; } @@ -10175,9 +10262,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { - _bits &= ~0x40000000L; + _bits &= ~0x80000000L; _headers._AccessControlAllowHeaders = default(StringValues); return true; } @@ -10185,9 +10272,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { - _bits &= ~0x80000000L; + _bits &= ~0x100000000L; _headers._AccessControlAllowMethods = default(StringValues); return true; } @@ -10196,9 +10283,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { - _bits &= ~0x40000000L; + _bits &= ~0x80000000L; _headers._AccessControlAllowHeaders = default(StringValues); return true; } @@ -10206,9 +10293,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { - _bits &= ~0x80000000L; + _bits &= ~0x100000000L; _headers._AccessControlAllowMethods = default(StringValues); return true; } @@ -10220,9 +10307,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { - _bits &= ~0x200000000L; + _bits &= ~0x400000000L; _headers._AccessControlExposeHeaders = default(StringValues); return true; } @@ -10231,9 +10318,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { - _bits &= ~0x200000000L; + _bits &= ~0x400000000L; _headers._AccessControlExposeHeaders = default(StringValues); return true; } @@ -10245,9 +10332,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { - _bits &= ~0x20000000L; + _bits &= ~0x40000000L; _headers._AccessControlAllowCredentials = default(StringValues); return true; } @@ -10256,9 +10343,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { - _bits &= ~0x20000000L; + _bits &= ~0x40000000L; _headers._AccessControlAllowCredentials = default(StringValues); return true; } @@ -10312,14 +10399,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http tempBits &= ~0x800L; } - if ((tempBits & 0x2000000L) != 0) + if ((tempBits & 0x4000000L) != 0) { _headers._Server = default; - if((tempBits & ~0x2000000L) == 0) + if((tempBits & ~0x4000000L) == 0) { return; } - tempBits &= ~0x2000000L; + tempBits &= ~0x4000000L; } if ((tempBits & 0x1L) != 0) @@ -10504,7 +10591,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x200000L) != 0) { - _headers._ETag = default; + _headers._AltSvc = default; if((tempBits & ~0x200000L) == 0) { return; @@ -10514,7 +10601,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x400000L) != 0) { - _headers._Location = default; + _headers._ETag = default; if((tempBits & ~0x400000L) == 0) { return; @@ -10524,7 +10611,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x800000L) != 0) { - _headers._ProxyAuthenticate = default; + _headers._Location = default; if((tempBits & ~0x800000L) == 0) { return; @@ -10534,7 +10621,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x1000000L) != 0) { - _headers._RetryAfter = default; + _headers._ProxyAuthenticate = default; if((tempBits & ~0x1000000L) == 0) { return; @@ -10542,19 +10629,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http tempBits &= ~0x1000000L; } - if ((tempBits & 0x4000000L) != 0) + if ((tempBits & 0x2000000L) != 0) { - _headers._SetCookie = default; - if((tempBits & ~0x4000000L) == 0) + _headers._RetryAfter = default; + if((tempBits & ~0x2000000L) == 0) { return; } - tempBits &= ~0x4000000L; + tempBits &= ~0x2000000L; } if ((tempBits & 0x8000000L) != 0) { - _headers._Vary = default; + _headers._SetCookie = default; if((tempBits & ~0x8000000L) == 0) { return; @@ -10564,7 +10651,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x10000000L) != 0) { - _headers._WWWAuthenticate = default; + _headers._Vary = default; if((tempBits & ~0x10000000L) == 0) { return; @@ -10574,7 +10661,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x20000000L) != 0) { - _headers._AccessControlAllowCredentials = default; + _headers._WWWAuthenticate = default; if((tempBits & ~0x20000000L) == 0) { return; @@ -10584,7 +10671,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x40000000L) != 0) { - _headers._AccessControlAllowHeaders = default; + _headers._AccessControlAllowCredentials = default; if((tempBits & ~0x40000000L) == 0) { return; @@ -10594,7 +10681,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x80000000L) != 0) { - _headers._AccessControlAllowMethods = default; + _headers._AccessControlAllowHeaders = default; if((tempBits & ~0x80000000L) == 0) { return; @@ -10604,7 +10691,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x100000000L) != 0) { - _headers._AccessControlAllowOrigin = default; + _headers._AccessControlAllowMethods = default; if((tempBits & ~0x100000000L) == 0) { return; @@ -10614,7 +10701,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x200000000L) != 0) { - _headers._AccessControlExposeHeaders = default; + _headers._AccessControlAllowOrigin = default; if((tempBits & ~0x200000000L) == 0) { return; @@ -10624,7 +10711,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x400000000L) != 0) { - _headers._AccessControlMaxAge = default; + _headers._AccessControlExposeHeaders = default; if((tempBits & ~0x400000000L) == 0) { return; @@ -10632,6 +10719,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http tempBits &= ~0x400000000L; } + if ((tempBits & 0x800000000L) != 0) + { + _headers._AccessControlMaxAge = default; + if((tempBits & ~0x800000000L) == 0) + { + return; + } + tempBits &= ~0x800000000L; + } + } protected override bool CopyToFast(KeyValuePair<string, StringValues>[] array, int arrayIndex) @@ -10836,7 +10933,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.ETag, _headers._ETag); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AltSvc, _headers._AltSvc); ++arrayIndex; } if ((_bits & 0x400000L) != 0) @@ -10845,7 +10942,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.Location, _headers._Location); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.ETag, _headers._ETag); ++arrayIndex; } if ((_bits & 0x800000L) != 0) @@ -10854,7 +10951,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.ProxyAuthenticate, _headers._ProxyAuthenticate); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.Location, _headers._Location); ++arrayIndex; } if ((_bits & 0x1000000L) != 0) @@ -10863,7 +10960,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.RetryAfter, _headers._RetryAfter); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.ProxyAuthenticate, _headers._ProxyAuthenticate); ++arrayIndex; } if ((_bits & 0x2000000L) != 0) @@ -10872,7 +10969,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.Server, _headers._Server); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.RetryAfter, _headers._RetryAfter); ++arrayIndex; } if ((_bits & 0x4000000L) != 0) @@ -10881,7 +10978,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.SetCookie, _headers._SetCookie); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.Server, _headers._Server); ++arrayIndex; } if ((_bits & 0x8000000L) != 0) @@ -10890,7 +10987,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.Vary, _headers._Vary); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.SetCookie, _headers._SetCookie); ++arrayIndex; } if ((_bits & 0x10000000L) != 0) @@ -10899,7 +10996,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.WWWAuthenticate, _headers._WWWAuthenticate); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.Vary, _headers._Vary); ++arrayIndex; } if ((_bits & 0x20000000L) != 0) @@ -10908,7 +11005,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowCredentials, _headers._AccessControlAllowCredentials); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.WWWAuthenticate, _headers._WWWAuthenticate); ++arrayIndex; } if ((_bits & 0x40000000L) != 0) @@ -10917,7 +11014,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowHeaders, _headers._AccessControlAllowHeaders); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowCredentials, _headers._AccessControlAllowCredentials); ++arrayIndex; } if ((_bits & 0x80000000L) != 0) @@ -10926,7 +11023,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowMethods, _headers._AccessControlAllowMethods); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowHeaders, _headers._AccessControlAllowHeaders); ++arrayIndex; } if ((_bits & 0x100000000L) != 0) @@ -10935,7 +11032,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowOrigin, _headers._AccessControlAllowOrigin); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowMethods, _headers._AccessControlAllowMethods); ++arrayIndex; } if ((_bits & 0x200000000L) != 0) @@ -10944,10 +11041,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return false; } - array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlExposeHeaders, _headers._AccessControlExposeHeaders); + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowOrigin, _headers._AccessControlAllowOrigin); ++arrayIndex; } if ((_bits & 0x400000000L) != 0) + { + if (arrayIndex == array.Length) + { + return false; + } + array[arrayIndex] = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlExposeHeaders, _headers._AccessControlExposeHeaders); + ++arrayIndex; + } + if ((_bits & 0x800000000L) != 0) { if (arrayIndex == array.Length) { @@ -11030,9 +11136,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } goto case 3; case 3: // Header: "Server" - if ((tempBits & 0x2000000L) != 0) + if ((tempBits & 0x4000000L) != 0) { - tempBits ^= 0x2000000L; + tempBits ^= 0x4000000L; if (_headers._rawServer != null) { output.Write(_headers._rawServer); @@ -11040,7 +11146,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http else { values = ref _headers._Server; - keyStart = 350; + keyStart = 361; keyLength = 10; next = 4; break; // OutputHeader @@ -11051,7 +11157,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http if ((tempBits & 0x8000000000000000L) != 0) { tempBits ^= 0x8000000000000000L; - output.Write(HeaderBytes.Slice(592, 18)); + output.Write(HeaderBytes.Slice(603, 18)); output.WriteNumeric((ulong)ContentLength.Value); if (tempBits == 0) { @@ -11264,148 +11370,159 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http break; // OutputHeader } goto case 23; - case 23: // Header: "ETag" + case 23: // Header: "Alt-Svc" if ((tempBits & 0x200000L) != 0) { tempBits ^= 0x200000L; - values = ref _headers._ETag; + values = ref _headers._AltSvc; keyStart = 293; - keyLength = 8; + keyLength = 11; next = 24; break; // OutputHeader } goto case 24; - case 24: // Header: "Location" + case 24: // Header: "ETag" if ((tempBits & 0x400000L) != 0) { tempBits ^= 0x400000L; - values = ref _headers._Location; - keyStart = 301; - keyLength = 12; + values = ref _headers._ETag; + keyStart = 304; + keyLength = 8; next = 25; break; // OutputHeader } goto case 25; - case 25: // Header: "Proxy-Authenticate" + case 25: // Header: "Location" if ((tempBits & 0x800000L) != 0) { tempBits ^= 0x800000L; - values = ref _headers._ProxyAuthenticate; - keyStart = 313; - keyLength = 22; + values = ref _headers._Location; + keyStart = 312; + keyLength = 12; next = 26; break; // OutputHeader } goto case 26; - case 26: // Header: "Retry-After" + case 26: // Header: "Proxy-Authenticate" if ((tempBits & 0x1000000L) != 0) { tempBits ^= 0x1000000L; - values = ref _headers._RetryAfter; - keyStart = 335; - keyLength = 15; + values = ref _headers._ProxyAuthenticate; + keyStart = 324; + keyLength = 22; next = 27; break; // OutputHeader } goto case 27; - case 27: // Header: "Set-Cookie" - if ((tempBits & 0x4000000L) != 0) + case 27: // Header: "Retry-After" + if ((tempBits & 0x2000000L) != 0) { - tempBits ^= 0x4000000L; - values = ref _headers._SetCookie; - keyStart = 360; - keyLength = 14; + tempBits ^= 0x2000000L; + values = ref _headers._RetryAfter; + keyStart = 346; + keyLength = 15; next = 28; break; // OutputHeader } goto case 28; - case 28: // Header: "Vary" + case 28: // Header: "Set-Cookie" if ((tempBits & 0x8000000L) != 0) { tempBits ^= 0x8000000L; - values = ref _headers._Vary; - keyStart = 374; - keyLength = 8; + values = ref _headers._SetCookie; + keyStart = 371; + keyLength = 14; next = 29; break; // OutputHeader } goto case 29; - case 29: // Header: "WWW-Authenticate" + case 29: // Header: "Vary" if ((tempBits & 0x10000000L) != 0) { tempBits ^= 0x10000000L; - values = ref _headers._WWWAuthenticate; - keyStart = 382; - keyLength = 20; + values = ref _headers._Vary; + keyStart = 385; + keyLength = 8; next = 30; break; // OutputHeader } goto case 30; - case 30: // Header: "Access-Control-Allow-Credentials" + case 30: // Header: "WWW-Authenticate" if ((tempBits & 0x20000000L) != 0) { tempBits ^= 0x20000000L; - values = ref _headers._AccessControlAllowCredentials; - keyStart = 402; - keyLength = 36; + values = ref _headers._WWWAuthenticate; + keyStart = 393; + keyLength = 20; next = 31; break; // OutputHeader } goto case 31; - case 31: // Header: "Access-Control-Allow-Headers" + case 31: // Header: "Access-Control-Allow-Credentials" if ((tempBits & 0x40000000L) != 0) { tempBits ^= 0x40000000L; - values = ref _headers._AccessControlAllowHeaders; - keyStart = 438; - keyLength = 32; + values = ref _headers._AccessControlAllowCredentials; + keyStart = 413; + keyLength = 36; next = 32; break; // OutputHeader } goto case 32; - case 32: // Header: "Access-Control-Allow-Methods" + case 32: // Header: "Access-Control-Allow-Headers" if ((tempBits & 0x80000000L) != 0) { tempBits ^= 0x80000000L; - values = ref _headers._AccessControlAllowMethods; - keyStart = 470; + values = ref _headers._AccessControlAllowHeaders; + keyStart = 449; keyLength = 32; next = 33; break; // OutputHeader } goto case 33; - case 33: // Header: "Access-Control-Allow-Origin" + case 33: // Header: "Access-Control-Allow-Methods" if ((tempBits & 0x100000000L) != 0) { tempBits ^= 0x100000000L; - values = ref _headers._AccessControlAllowOrigin; - keyStart = 502; - keyLength = 31; + values = ref _headers._AccessControlAllowMethods; + keyStart = 481; + keyLength = 32; next = 34; break; // OutputHeader } goto case 34; - case 34: // Header: "Access-Control-Expose-Headers" + case 34: // Header: "Access-Control-Allow-Origin" if ((tempBits & 0x200000000L) != 0) { tempBits ^= 0x200000000L; - values = ref _headers._AccessControlExposeHeaders; - keyStart = 533; - keyLength = 33; + values = ref _headers._AccessControlAllowOrigin; + keyStart = 513; + keyLength = 31; next = 35; break; // OutputHeader } goto case 35; - case 35: // Header: "Access-Control-Max-Age" + case 35: // Header: "Access-Control-Expose-Headers" if ((tempBits & 0x400000000L) != 0) { tempBits ^= 0x400000000L; - values = ref _headers._AccessControlMaxAge; - keyStart = 566; - keyLength = 26; + values = ref _headers._AccessControlExposeHeaders; + keyStart = 544; + keyLength = 33; next = 36; break; // OutputHeader } + goto case 36; + case 36: // Header: "Access-Control-Max-Age" + if ((tempBits & 0x800000000L) != 0) + { + tempBits ^= 0x800000000L; + values = ref _headers._AccessControlMaxAge; + keyStart = 577; + keyLength = 26; + next = 37; + break; // OutputHeader + } return; default: return; @@ -11451,6 +11568,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public StringValues _LastModified; public StringValues _AcceptRanges; public StringValues _Age; + public StringValues _AltSvc; public StringValues _ETag; public StringValues _Location; public StringValues _ProxyAuthenticate; @@ -11522,34 +11640,36 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http case 20: goto HeaderAge; case 21: - goto HeaderETag; + goto HeaderAltSvc; case 22: - goto HeaderLocation; + goto HeaderETag; case 23: - goto HeaderProxyAuthenticate; + goto HeaderLocation; case 24: - goto HeaderRetryAfter; + goto HeaderProxyAuthenticate; case 25: - goto HeaderServer; + goto HeaderRetryAfter; case 26: - goto HeaderSetCookie; + goto HeaderServer; case 27: - goto HeaderVary; + goto HeaderSetCookie; case 28: - goto HeaderWWWAuthenticate; + goto HeaderVary; case 29: - goto HeaderAccessControlAllowCredentials; + goto HeaderWWWAuthenticate; case 30: - goto HeaderAccessControlAllowHeaders; + goto HeaderAccessControlAllowCredentials; case 31: - goto HeaderAccessControlAllowMethods; + goto HeaderAccessControlAllowHeaders; case 32: - goto HeaderAccessControlAllowOrigin; + goto HeaderAccessControlAllowMethods; case 33: - goto HeaderAccessControlExposeHeaders; + goto HeaderAccessControlAllowOrigin; case 34: - goto HeaderAccessControlMaxAge; + goto HeaderAccessControlExposeHeaders; case 35: + goto HeaderAccessControlMaxAge; + case 36: goto HeaderContentLength; default: goto ExtraHeaders; @@ -11702,109 +11822,116 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _next = 21; return true; } - HeaderETag: // case 21 + HeaderAltSvc: // case 21 if ((_bits & 0x200000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.ETag, _collection._headers._ETag); + _current = new KeyValuePair<string, StringValues>(HeaderNames.AltSvc, _collection._headers._AltSvc); _next = 22; return true; } - HeaderLocation: // case 22 + HeaderETag: // case 22 if ((_bits & 0x400000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.Location, _collection._headers._Location); + _current = new KeyValuePair<string, StringValues>(HeaderNames.ETag, _collection._headers._ETag); _next = 23; return true; } - HeaderProxyAuthenticate: // case 23 + HeaderLocation: // case 23 if ((_bits & 0x800000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.ProxyAuthenticate, _collection._headers._ProxyAuthenticate); + _current = new KeyValuePair<string, StringValues>(HeaderNames.Location, _collection._headers._Location); _next = 24; return true; } - HeaderRetryAfter: // case 24 + HeaderProxyAuthenticate: // case 24 if ((_bits & 0x1000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.RetryAfter, _collection._headers._RetryAfter); + _current = new KeyValuePair<string, StringValues>(HeaderNames.ProxyAuthenticate, _collection._headers._ProxyAuthenticate); _next = 25; return true; } - HeaderServer: // case 25 + HeaderRetryAfter: // case 25 if ((_bits & 0x2000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.Server, _collection._headers._Server); + _current = new KeyValuePair<string, StringValues>(HeaderNames.RetryAfter, _collection._headers._RetryAfter); _next = 26; return true; } - HeaderSetCookie: // case 26 + HeaderServer: // case 26 if ((_bits & 0x4000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.SetCookie, _collection._headers._SetCookie); + _current = new KeyValuePair<string, StringValues>(HeaderNames.Server, _collection._headers._Server); _next = 27; return true; } - HeaderVary: // case 27 + HeaderSetCookie: // case 27 if ((_bits & 0x8000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.Vary, _collection._headers._Vary); + _current = new KeyValuePair<string, StringValues>(HeaderNames.SetCookie, _collection._headers._SetCookie); _next = 28; return true; } - HeaderWWWAuthenticate: // case 28 + HeaderVary: // case 28 if ((_bits & 0x10000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.WWWAuthenticate, _collection._headers._WWWAuthenticate); + _current = new KeyValuePair<string, StringValues>(HeaderNames.Vary, _collection._headers._Vary); _next = 29; return true; } - HeaderAccessControlAllowCredentials: // case 29 + HeaderWWWAuthenticate: // case 29 if ((_bits & 0x20000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowCredentials, _collection._headers._AccessControlAllowCredentials); + _current = new KeyValuePair<string, StringValues>(HeaderNames.WWWAuthenticate, _collection._headers._WWWAuthenticate); _next = 30; return true; } - HeaderAccessControlAllowHeaders: // case 30 + HeaderAccessControlAllowCredentials: // case 30 if ((_bits & 0x40000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowHeaders, _collection._headers._AccessControlAllowHeaders); + _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowCredentials, _collection._headers._AccessControlAllowCredentials); _next = 31; return true; } - HeaderAccessControlAllowMethods: // case 31 + HeaderAccessControlAllowHeaders: // case 31 if ((_bits & 0x80000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowMethods, _collection._headers._AccessControlAllowMethods); + _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowHeaders, _collection._headers._AccessControlAllowHeaders); _next = 32; return true; } - HeaderAccessControlAllowOrigin: // case 32 + HeaderAccessControlAllowMethods: // case 32 if ((_bits & 0x100000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowOrigin, _collection._headers._AccessControlAllowOrigin); + _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowMethods, _collection._headers._AccessControlAllowMethods); _next = 33; return true; } - HeaderAccessControlExposeHeaders: // case 33 + HeaderAccessControlAllowOrigin: // case 33 if ((_bits & 0x200000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlExposeHeaders, _collection._headers._AccessControlExposeHeaders); + _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlAllowOrigin, _collection._headers._AccessControlAllowOrigin); _next = 34; return true; } - HeaderAccessControlMaxAge: // case 34 + HeaderAccessControlExposeHeaders: // case 34 if ((_bits & 0x400000000L) != 0) { - _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlMaxAge, _collection._headers._AccessControlMaxAge); + _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlExposeHeaders, _collection._headers._AccessControlExposeHeaders); _next = 35; return true; } - HeaderContentLength: // case 35 + HeaderAccessControlMaxAge: // case 35 + if ((_bits & 0x800000000L) != 0) + { + _current = new KeyValuePair<string, StringValues>(HeaderNames.AccessControlMaxAge, _collection._headers._AccessControlMaxAge); + _next = 36; + return true; + } + HeaderContentLength: // case 36 if (_collection._contentLength.HasValue) { _current = new KeyValuePair<string, StringValues>(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.Value)); - _next = 36; + _next = 37; return true; } ExtraHeaders: diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs index d041705a19..e1175fcde9 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs @@ -27,6 +27,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http get { return _contentLength; } set { + if (_isReadOnly) + { + ThrowHeadersReadOnlyException(); + } if (value.HasValue && value.Value < 0) { ThrowInvalidContentLengthException(value.Value); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs index 2fe5dfdb36..6d02b95728 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; using System.Diagnostics; +using System.Net.Http; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; @@ -31,6 +32,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private const byte ByteTab = (byte)'\t'; private const byte ByteQuestionMark = (byte)'?'; private const byte BytePercentage = (byte)'%'; + private const int MinTlsRequestSize = 1; // We need at least 1 byte to check for a proper TLS request line public unsafe bool ParseRequestLine(TRequestHandler handler, in ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined) { @@ -211,7 +213,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } // Double CRLF found, so end of headers. - handler.OnHeadersComplete(); + handler.OnHeadersComplete(endStream: false); return true; } else if (readAhead == 1) @@ -415,9 +417,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return new Span<byte>(data, methodLength); } + private unsafe bool IsTlsHandshake(byte* data, int length) + { + const byte SslRecordTypeHandshake = (byte)0x16; + + // Make sure we can check at least for the existence of a TLS handshake - we check the first byte + // See https://serializethoughts.com/2014/07/27/dissecting-tls-client-hello-message/ + + return (length >= MinTlsRequestSize && data[0] == SslRecordTypeHandshake); + } + [StackTraceHidden] private unsafe void RejectRequestLine(byte* requestLine, int length) - => throw GetInvalidRequestException(RequestRejectionReason.InvalidRequestLine, requestLine, length); + { + // Check for incoming TLS handshake over HTTP + if (IsTlsHandshake(requestLine, length)) + { + throw GetInvalidRequestException(RequestRejectionReason.TlsOverHttpError, requestLine, length); + } + else + { + throw GetInvalidRequestException(RequestRejectionReason.InvalidRequestLine, requestLine, length); + } + } [StackTraceHidden] private unsafe void RejectRequestHeader(byte* headerLine, int length) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index 7f10c3af64..cc4377af1d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -155,6 +155,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { return HttpUtilities.Http2Version; } + if (_httpVersion == Http.HttpVersion.Http3) + { + return HttpUtilities.Http3Version; + } return string.Empty; } @@ -176,6 +180,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { _httpVersion = Http.HttpVersion.Http2; } + else if (ReferenceEquals(value, HttpUtilities.Http3Version)) + { + _httpVersion = Http.HttpVersion.Http3; + } else { HttpVersionSetSlow(value); @@ -198,6 +206,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { _httpVersion = Http.HttpVersion.Http2; } + else if (value == HttpUtilities.Http3Version) + { + _httpVersion = Http.HttpVersion.Http3; + } else { _httpVersion = Http.HttpVersion.Unknown; @@ -492,7 +504,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { _requestHeadersParsed++; if (_requestHeadersParsed > ServerOptions.Limits.MaxRequestHeaderCount) @@ -503,7 +515,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http HttpRequestHeaders.Append(name, value); } - public void OnTrailer(Span<byte> name, Span<byte> value) + public void OnTrailer(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { // Trailers still count towards the limit. _requestHeadersParsed++; @@ -1044,7 +1056,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private Task WriteSuffix() { - if (_autoChunk || _httpVersion == Http.HttpVersion.Http2) + if (_autoChunk || _httpVersion >= Http.HttpVersion.Http2) { // For the same reason we call CheckLastWrite() in Content-Length responses. PreventRequestAbortedCancellation(); @@ -1160,7 +1172,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http responseHeaders.SetReadOnly(); - if (!hasConnection && _httpVersion != Http.HttpVersion.Http2) + if (!hasConnection && _httpVersion < Http.HttpVersion.Http2) { if (!_keepAlive) { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs index 32e9e41d84..66ae0aad54 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } [MethodImpl(MethodImplOptions.NoInlining)] - private void AppendContentLength(Span<byte> value) + private void AppendContentLength(ReadOnlySpan<byte> value) { if (_contentLength.HasValue) { @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } [MethodImpl(MethodImplOptions.NoInlining)] - private unsafe void AppendUnknownHeaders(Span<byte> name, string valueString) + private unsafe void AppendUnknownHeaders(ReadOnlySpan<byte> name, string valueString) { string key = name.GetHeaderName(); Unknown.TryGetValue(key, out var existing); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs index 4d5513293e..a1b30fb940 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs @@ -90,41 +90,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = ReadAsync(buffer, offset, count, default, state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); } /// <inheritdoc /> public override int EndRead(IAsyncResult asyncResult) { - return ((Task<int>)asyncResult).GetAwaiter().GetResult(); - } - - private Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<int>(state); - var task = ReadAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<int>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(task2.Result); - } - }, tcs, cancellationToken); - return tcs.Task; + return TaskToApm.End<int>(asyncResult); } private ValueTask<int> ReadAsyncWrapper(Memory<byte> destination, CancellationToken cancellationToken) @@ -139,7 +111,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } - private async ValueTask<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken) + private async ValueTask<int> ReadAsyncInternal(Memory<byte> destination, CancellationToken cancellationToken) { while (true) { @@ -150,19 +122,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http throw new OperationCanceledException("The read was canceled"); } - var readableBuffer = result.Buffer; - var readableBufferLength = readableBuffer.Length; + var buffer = result.Buffer; + var length = buffer.Length; - var consumed = readableBuffer.End; + var consumed = buffer.End; try { - if (readableBufferLength != 0) + if (length != 0) { - var actual = (int)Math.Min(readableBufferLength, buffer.Length); + var actual = (int)Math.Min(length, destination.Length); - var slice = actual == readableBufferLength ? readableBuffer : readableBuffer.Slice(0, actual); + var slice = actual == length ? buffer : buffer.Slice(0, actual); consumed = slice.End; - slice.CopyTo(buffer.Span); + slice.CopyTo(destination.Span); return actual; } @@ -193,37 +165,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http throw new ArgumentOutOfRangeException(nameof(bufferSize)); } - return CopyToAsyncInternal(destination, cancellationToken); - } - - private async Task CopyToAsyncInternal(Stream destination, CancellationToken cancellationToken) - { - while (true) - { - var result = await _pipeReader.ReadAsync(cancellationToken); - var readableBuffer = result.Buffer; - var readableBufferLength = readableBuffer.Length; - - try - { - if (readableBufferLength != 0) - { - foreach (var memory in readableBuffer) - { - await destination.WriteAsync(memory, cancellationToken); - } - } - - if (result.IsCompleted) - { - return; - } - } - finally - { - _pipeReader.AdvanceTo(readableBuffer.End); - } - } + return _pipeReader.CopyToAsync(destination, cancellationToken); } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs index 0af675600f..a87a22f56a 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs @@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal sealed partial class HttpResponseHeaders : HttpHeaders { + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static private static ReadOnlySpan<byte> CrLf => new[] { (byte)'\r', (byte)'\n' }; private static ReadOnlySpan<byte> ColonSpace => new[] { (byte)':', (byte)' ' }; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseStream.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseStream.cs index 2bf5017278..86ddb9b157 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseStream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseStream.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using System.IO.Pipelines; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Features; @@ -87,40 +86,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = WriteAsync(buffer, offset, count, default, state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); } public override void EndWrite(IAsyncResult asyncResult) { - ((Task<object>)asyncResult).GetAwaiter().GetResult(); - } - - private Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<object>(state); - var task = WriteAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<object>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(null); - } - }, tcs, cancellationToken); - return tcs.Task; + TaskToApm.End(asyncResult); } public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpVersion.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpVersion.cs index 832a1c5616..e6e2a0dabf 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpVersion.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpVersion.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http @@ -8,6 +8,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http Unknown = -1, Http10 = 0, Http11 = 1, - Http2 + Http2 = 2, + Http3 = 3 } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/IHttpParser.cs b/src/Servers/Kestrel/Core/src/Internal/Http/IHttpParser.cs index 18837ccd0a..20688fe291 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/IHttpParser.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/IHttpParser.cs @@ -3,10 +3,11 @@ using System; using System.Buffers; +using System.Net.Http; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { - public interface IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler + internal interface IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler { bool ParseRequestLine(TRequestHandler handler, in ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/RequestRejectionReason.cs b/src/Servers/Kestrel/Core/src/Internal/Http/RequestRejectionReason.cs index fce21b6210..23dc6c67c6 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/RequestRejectionReason.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/RequestRejectionReason.cs @@ -1,10 +1,11 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal enum RequestRejectionReason { + TlsOverHttpError, UnrecognizedHTTPVersion, InvalidRequestLine, InvalidRequestHeader, diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecoder.cs deleted file mode 100644 index 543ce8afc1..0000000000 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecoder.cs +++ /dev/null @@ -1,433 +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. - -using System; -using System.Buffers; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack -{ - internal class HPackDecoder - { - private enum State - { - Ready, - HeaderFieldIndex, - HeaderNameIndex, - HeaderNameLength, - HeaderNameLengthContinue, - HeaderName, - HeaderValueLength, - HeaderValueLengthContinue, - HeaderValue, - DynamicTableSizeUpdate - } - - // http://httpwg.org/specs/rfc7541.html#rfc.section.6.1 - // 0 1 2 3 4 5 6 7 - // +---+---+---+---+---+---+---+---+ - // | 1 | Index (7+) | - // +---+---------------------------+ - private const byte IndexedHeaderFieldMask = 0x80; - private const byte IndexedHeaderFieldRepresentation = 0x80; - - // http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 - // 0 1 2 3 4 5 6 7 - // +---+---+---+---+---+---+---+---+ - // | 0 | 1 | Index (6+) | - // +---+---+-----------------------+ - private const byte LiteralHeaderFieldWithIncrementalIndexingMask = 0xc0; - private const byte LiteralHeaderFieldWithIncrementalIndexingRepresentation = 0x40; - - // http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 - // 0 1 2 3 4 5 6 7 - // +---+---+---+---+---+---+---+---+ - // | 0 | 0 | 0 | 0 | Index (4+) | - // +---+---+-----------------------+ - private const byte LiteralHeaderFieldWithoutIndexingMask = 0xf0; - private const byte LiteralHeaderFieldWithoutIndexingRepresentation = 0x00; - - // http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 - // 0 1 2 3 4 5 6 7 - // +---+---+---+---+---+---+---+---+ - // | 0 | 0 | 0 | 1 | Index (4+) | - // +---+---+-----------------------+ - private const byte LiteralHeaderFieldNeverIndexedMask = 0xf0; - private const byte LiteralHeaderFieldNeverIndexedRepresentation = 0x10; - - // http://httpwg.org/specs/rfc7541.html#rfc.section.6.3 - // 0 1 2 3 4 5 6 7 - // +---+---+---+---+---+---+---+---+ - // | 0 | 0 | 1 | Max size (5+) | - // +---+---------------------------+ - private const byte DynamicTableSizeUpdateMask = 0xe0; - private const byte DynamicTableSizeUpdateRepresentation = 0x20; - - // http://httpwg.org/specs/rfc7541.html#rfc.section.5.2 - // 0 1 2 3 4 5 6 7 - // +---+---+---+---+---+---+---+---+ - // | H | String Length (7+) | - // +---+---------------------------+ - private const byte HuffmanMask = 0x80; - - private const int IndexedHeaderFieldPrefix = 7; - private const int LiteralHeaderFieldWithIncrementalIndexingPrefix = 6; - private const int LiteralHeaderFieldWithoutIndexingPrefix = 4; - private const int LiteralHeaderFieldNeverIndexedPrefix = 4; - private const int DynamicTableSizeUpdatePrefix = 5; - private const int StringLengthPrefix = 7; - - private readonly int _maxDynamicTableSize; - private readonly DynamicTable _dynamicTable; - private readonly IntegerDecoder _integerDecoder = new IntegerDecoder(); - private readonly byte[] _stringOctets; - private readonly byte[] _headerNameOctets; - private readonly byte[] _headerValueOctets; - - private State _state = State.Ready; - private byte[] _headerName; - private int _stringIndex; - private int _stringLength; - private int _headerNameLength; - private int _headerValueLength; - private bool _index; - private bool _huffman; - private bool _headersObserved; - - public HPackDecoder(int maxDynamicTableSize, int maxRequestHeaderFieldSize) - : this(maxDynamicTableSize, maxRequestHeaderFieldSize, new DynamicTable(maxDynamicTableSize)) { } - - // For testing. - internal HPackDecoder(int maxDynamicTableSize, int maxRequestHeaderFieldSize, DynamicTable dynamicTable) - { - _maxDynamicTableSize = maxDynamicTableSize; - _dynamicTable = dynamicTable; - - _stringOctets = new byte[maxRequestHeaderFieldSize]; - _headerNameOctets = new byte[maxRequestHeaderFieldSize]; - _headerValueOctets = new byte[maxRequestHeaderFieldSize]; - } - - public void Decode(in ReadOnlySequence<byte> data, bool endHeaders, IHttpHeadersHandler handler) - { - foreach (var segment in data) - { - var span = segment.Span; - for (var i = 0; i < span.Length; i++) - { - OnByte(span[i], handler); - } - } - - if (endHeaders) - { - if (_state != State.Ready) - { - throw new HPackDecodingException(CoreStrings.HPackErrorIncompleteHeaderBlock); - } - - _headersObserved = false; - } - } - - private void OnByte(byte b, IHttpHeadersHandler handler) - { - int intResult; - switch (_state) - { - case State.Ready: - if ((b & IndexedHeaderFieldMask) == IndexedHeaderFieldRepresentation) - { - _headersObserved = true; - var val = b & ~IndexedHeaderFieldMask; - - if (_integerDecoder.BeginTryDecode((byte)val, IndexedHeaderFieldPrefix, out intResult)) - { - OnIndexedHeaderField(intResult, handler); - } - else - { - _state = State.HeaderFieldIndex; - } - } - else if ((b & LiteralHeaderFieldWithIncrementalIndexingMask) == LiteralHeaderFieldWithIncrementalIndexingRepresentation) - { - _headersObserved = true; - _index = true; - var val = b & ~LiteralHeaderFieldWithIncrementalIndexingMask; - - if (val == 0) - { - _state = State.HeaderNameLength; - } - else if (_integerDecoder.BeginTryDecode((byte)val, LiteralHeaderFieldWithIncrementalIndexingPrefix, out intResult)) - { - OnIndexedHeaderName(intResult); - } - else - { - _state = State.HeaderNameIndex; - } - } - else if ((b & LiteralHeaderFieldWithoutIndexingMask) == LiteralHeaderFieldWithoutIndexingRepresentation) - { - _headersObserved = true; - _index = false; - var val = b & ~LiteralHeaderFieldWithoutIndexingMask; - - if (val == 0) - { - _state = State.HeaderNameLength; - } - else if (_integerDecoder.BeginTryDecode((byte)val, LiteralHeaderFieldWithoutIndexingPrefix, out intResult)) - { - OnIndexedHeaderName(intResult); - } - else - { - _state = State.HeaderNameIndex; - } - } - else if ((b & LiteralHeaderFieldNeverIndexedMask) == LiteralHeaderFieldNeverIndexedRepresentation) - { - _headersObserved = true; - _index = false; - var val = b & ~LiteralHeaderFieldNeverIndexedMask; - - if (val == 0) - { - _state = State.HeaderNameLength; - } - else if (_integerDecoder.BeginTryDecode((byte)val, LiteralHeaderFieldNeverIndexedPrefix, out intResult)) - { - OnIndexedHeaderName(intResult); - } - else - { - _state = State.HeaderNameIndex; - } - } - else if ((b & DynamicTableSizeUpdateMask) == DynamicTableSizeUpdateRepresentation) - { - // https://tools.ietf.org/html/rfc7541#section-4.2 - // This dynamic table size - // update MUST occur at the beginning of the first header block - // following the change to the dynamic table size. - if (_headersObserved) - { - throw new HPackDecodingException(CoreStrings.HPackErrorDynamicTableSizeUpdateNotAtBeginningOfHeaderBlock); - } - - if (_integerDecoder.BeginTryDecode((byte)(b & ~DynamicTableSizeUpdateMask), DynamicTableSizeUpdatePrefix, out intResult)) - { - SetDynamicHeaderTableSize(intResult); - } - else - { - _state = State.DynamicTableSizeUpdate; - } - } - else - { - // Can't happen - throw new HPackDecodingException($"Byte value {b} does not encode a valid header field representation."); - } - - break; - case State.HeaderFieldIndex: - if (_integerDecoder.TryDecode(b, out intResult)) - { - OnIndexedHeaderField(intResult, handler); - } - - break; - case State.HeaderNameIndex: - if (_integerDecoder.TryDecode(b, out intResult)) - { - OnIndexedHeaderName(intResult); - } - - break; - case State.HeaderNameLength: - _huffman = (b & HuffmanMask) != 0; - - if (_integerDecoder.BeginTryDecode((byte)(b & ~HuffmanMask), StringLengthPrefix, out intResult)) - { - OnStringLength(intResult, nextState: State.HeaderName); - } - else - { - _state = State.HeaderNameLengthContinue; - } - - break; - case State.HeaderNameLengthContinue: - if (_integerDecoder.TryDecode(b, out intResult)) - { - OnStringLength(intResult, nextState: State.HeaderName); - } - - break; - case State.HeaderName: - _stringOctets[_stringIndex++] = b; - - if (_stringIndex == _stringLength) - { - OnString(nextState: State.HeaderValueLength); - } - - break; - case State.HeaderValueLength: - _huffman = (b & HuffmanMask) != 0; - - if (_integerDecoder.BeginTryDecode((byte)(b & ~HuffmanMask), StringLengthPrefix, out intResult)) - { - OnStringLength(intResult, nextState: State.HeaderValue); - if (intResult == 0) - { - ProcessHeaderValue(handler); - } - } - else - { - _state = State.HeaderValueLengthContinue; - } - - break; - case State.HeaderValueLengthContinue: - if (_integerDecoder.TryDecode(b, out intResult)) - { - OnStringLength(intResult, nextState: State.HeaderValue); - if (intResult == 0) - { - ProcessHeaderValue(handler); - } - } - - break; - case State.HeaderValue: - _stringOctets[_stringIndex++] = b; - - if (_stringIndex == _stringLength) - { - ProcessHeaderValue(handler); - } - - break; - case State.DynamicTableSizeUpdate: - if (_integerDecoder.TryDecode(b, out intResult)) - { - SetDynamicHeaderTableSize(intResult); - _state = State.Ready; - } - - break; - default: - // Can't happen - throw new HPackDecodingException("The HPACK decoder reached an invalid state."); - } - } - - private void ProcessHeaderValue(IHttpHeadersHandler handler) - { - OnString(nextState: State.Ready); - - var headerNameSpan = new Span<byte>(_headerName, 0, _headerNameLength); - var headerValueSpan = new Span<byte>(_headerValueOctets, 0, _headerValueLength); - - handler.OnHeader(headerNameSpan, headerValueSpan); - - if (_index) - { - _dynamicTable.Insert(headerNameSpan, headerValueSpan); - } - } - - private void OnIndexedHeaderField(int index, IHttpHeadersHandler handler) - { - var header = GetHeader(index); - handler.OnHeader(new Span<byte>(header.Name), new Span<byte>(header.Value)); - _state = State.Ready; - } - - private void OnIndexedHeaderName(int index) - { - var header = GetHeader(index); - _headerName = header.Name; - _headerNameLength = header.Name.Length; - _state = State.HeaderValueLength; - } - - private void OnStringLength(int length, State nextState) - { - if (length > _stringOctets.Length) - { - throw new HPackDecodingException(CoreStrings.FormatHPackStringLengthTooLarge(length, _stringOctets.Length)); - } - - _stringLength = length; - _stringIndex = 0; - _state = nextState; - } - - private void OnString(State nextState) - { - int Decode(byte[] dst) - { - if (_huffman) - { - return Huffman.Decode(new ReadOnlySpan<byte>(_stringOctets, 0, _stringLength), dst); - } - else - { - Buffer.BlockCopy(_stringOctets, 0, dst, 0, _stringLength); - return _stringLength; - } - } - - try - { - if (_state == State.HeaderName) - { - _headerName = _headerNameOctets; - _headerNameLength = Decode(_headerNameOctets); - } - else - { - _headerValueLength = Decode(_headerValueOctets); - } - } - catch (HuffmanDecodingException ex) - { - throw new HPackDecodingException(CoreStrings.HPackHuffmanError, ex); - } - - _state = nextState; - } - - private HeaderField GetHeader(int index) - { - try - { - return index <= StaticTable.Instance.Count - ? StaticTable.Instance[index - 1] - : _dynamicTable[index - StaticTable.Instance.Count - 1]; - } - catch (IndexOutOfRangeException ex) - { - throw new HPackDecodingException(CoreStrings.FormatHPackErrorIndexOutOfRange(index), ex); - } - } - - private void SetDynamicHeaderTableSize(int size) - { - if (size > _maxDynamicTableSize) - { - throw new HPackDecodingException( - CoreStrings.FormatHPackErrorDynamicTableSizeUpdateTooLarge(size, _maxDynamicTableSize)); - } - - _dynamicTable.Resize(size); - } - } -} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackEncoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackEncoder.cs deleted file mode 100644 index 9268061b28..0000000000 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackEncoder.cs +++ /dev/null @@ -1,160 +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. - -using System; -using System.Collections.Generic; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack -{ - internal class HPackEncoder - { - private IEnumerator<KeyValuePair<string, string>> _enumerator; - - public bool BeginEncode(IEnumerable<KeyValuePair<string, string>> headers, Span<byte> buffer, out int length) - { - _enumerator = headers.GetEnumerator(); - _enumerator.MoveNext(); - - return Encode(buffer, out length); - } - - public bool BeginEncode(int statusCode, IEnumerable<KeyValuePair<string, string>> headers, Span<byte> buffer, out int length) - { - _enumerator = headers.GetEnumerator(); - _enumerator.MoveNext(); - - var statusCodeLength = EncodeStatusCode(statusCode, buffer); - var done = Encode(buffer.Slice(statusCodeLength), throwIfNoneEncoded: false, out var headersLength); - length = statusCodeLength + headersLength; - - return done; - } - - public bool Encode(Span<byte> buffer, out int length) - { - return Encode(buffer, throwIfNoneEncoded: true, out length); - } - - private bool Encode(Span<byte> buffer, bool throwIfNoneEncoded, out int length) - { - length = 0; - - do - { - if (!EncodeHeader(_enumerator.Current.Key, _enumerator.Current.Value, buffer.Slice(length), out var headerLength)) - { - if (length == 0 && throwIfNoneEncoded) - { - throw new HPackEncodingException(CoreStrings.HPackErrorNotEnoughBuffer); - } - return false; - } - - length += headerLength; - } while (_enumerator.MoveNext()); - - return true; - } - - private int EncodeStatusCode(int statusCode, Span<byte> buffer) - { - switch (statusCode) - { - case 200: - case 204: - case 206: - case 304: - case 400: - case 404: - case 500: - buffer[0] = (byte)(0x80 | StaticTable.Instance.StatusIndex[statusCode]); - return 1; - default: - // Send as Literal Header Field Without Indexing - Indexed Name - buffer[0] = 0x08; - - var statusBytes = StatusCodes.ToStatusBytes(statusCode); - buffer[1] = (byte)statusBytes.Length; - ((Span<byte>)statusBytes).CopyTo(buffer.Slice(2)); - - return 2 + statusBytes.Length; - } - } - - private bool EncodeHeader(string name, string value, Span<byte> buffer, out int length) - { - var i = 0; - length = 0; - - if (buffer.Length == 0) - { - return false; - } - - buffer[i++] = 0; - - if (i == buffer.Length) - { - return false; - } - - if (!EncodeString(name, buffer.Slice(i), out var nameLength, lowercase: true)) - { - return false; - } - - i += nameLength; - - if (i >= buffer.Length) - { - return false; - } - - if (!EncodeString(value, buffer.Slice(i), out var valueLength, lowercase: false)) - { - return false; - } - - i += valueLength; - - length = i; - return true; - } - - private bool EncodeString(string s, Span<byte> buffer, out int length, bool lowercase) - { - const int toLowerMask = 0x20; - - var i = 0; - length = 0; - - if (buffer.Length == 0) - { - return false; - } - - buffer[0] = 0; - - if (!IntegerEncoder.Encode(s.Length, 7, buffer, out var nameLength)) - { - return false; - } - - i += nameLength; - - // TODO: use huffman encoding - for (var j = 0; j < s.Length; j++) - { - if (i >= buffer.Length) - { - return false; - } - - buffer[i++] = (byte)(s[j] | (lowercase && s[j] >= (byte)'A' && s[j] <= (byte)'Z' ? toLowerMask : 0)); - } - - length = i; - return true; - } - } -} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerDecoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerDecoder.cs deleted file mode 100644 index 081fd30f6c..0000000000 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerDecoder.cs +++ /dev/null @@ -1,67 +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. - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack -{ - /// <summary> - /// The maximum we will decode is Int32.MaxValue, which is also the maximum request header field size. - /// </summary> - internal class IntegerDecoder - { - private int _i; - private int _m; - - /// <summary> - /// Callers must ensure higher bits above the prefix are cleared before calling this method. - /// </summary> - /// <param name="b"></param> - /// <param name="prefixLength"></param> - /// <param name="result"></param> - /// <returns></returns> - public bool BeginTryDecode(byte b, int prefixLength, out int result) - { - if (b < ((1 << prefixLength) - 1)) - { - result = b; - return true; - } - - _i = b; - _m = 0; - result = 0; - return false; - } - - public bool TryDecode(byte b, out int result) - { - var m = _m; // Enregister - var i = _i + ((b & 0x7f) << m); // Enregister - - if ((b & 0x80) == 0) - { - // Int32.MaxValue only needs a maximum of 5 bytes to represent and the last byte cannot have any value set larger than 0x7 - if ((m > 21 && b > 0x7) || i < 0) - { - ThrowIntegerTooBigException(); - } - - result = i; - return true; - } - else if (m > 21) - { - // Int32.MaxValue only needs a maximum of 5 bytes to represent - ThrowIntegerTooBigException(); - } - - _m = m + 7; - _i = i; - - result = 0; - return false; - } - - public static void ThrowIntegerTooBigException() - => throw new HPackDecodingException(CoreStrings.HPackErrorIntegerTooBig); - } -} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs deleted file mode 100644 index 600d032176..0000000000 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs +++ /dev/null @@ -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. - -using System; -using System.Diagnostics; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack -{ - internal static class IntegerEncoder - { - public static bool Encode(int i, int n, Span<byte> buffer, out int length) - { - Debug.Assert(i >= 0); - Debug.Assert(n >= 1 && n <= 8); - - var j = 0; - length = 0; - - if (buffer.Length == 0) - { - return false; - } - - if (i < (1 << n) - 1) - { - buffer[j] &= MaskHigh(8 - n); - buffer[j++] |= (byte)i; - } - else - { - buffer[j] &= MaskHigh(8 - n); - buffer[j++] |= (byte)((1 << n) - 1); - - if (j == buffer.Length) - { - return false; - } - - i -= ((1 << n) - 1); - while (i >= 128) - { - var ui = (uint)i; // Use unsigned for optimizations - buffer[j++] = (byte)((ui % 128) + 128); - - if (j >= buffer.Length) - { - return false; - } - - i = (int)(ui / 128); // Jit converts unsigned divide by power-of-2 constant to clean shift - } - buffer[j++] = (byte)i; - } - - length = j; - return true; - } - - private static byte MaskHigh(int n) - { - return (byte)(sbyte.MinValue >> (n - 1)); - } - } -} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StaticTable.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StaticTable.cs deleted file mode 100644 index 5c0ece5c9f..0000000000 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StaticTable.cs +++ /dev/null @@ -1,105 +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. - -using System.Collections.Generic; -using System.Text; -using Microsoft.Net.Http.Headers; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack -{ - internal class StaticTable - { - private static readonly StaticTable _instance = new StaticTable(); - - private readonly Dictionary<int, int> _statusIndex = new Dictionary<int, int> - { - [200] = 8, - [204] = 9, - [206] = 10, - [304] = 11, - [400] = 12, - [404] = 13, - [500] = 14, - }; - - private StaticTable() - { - } - - public static StaticTable Instance => _instance; - - public int Count => _staticTable.Length; - - public HeaderField this[int index] => _staticTable[index]; - - public IReadOnlyDictionary<int, int> StatusIndex => _statusIndex; - - private readonly HeaderField[] _staticTable = new HeaderField[] - { - CreateHeaderField(HeaderNames.Authority, ""), - CreateHeaderField(HeaderNames.Method, "GET"), - CreateHeaderField(HeaderNames.Method, "POST"), - CreateHeaderField(HeaderNames.Path, "/"), - CreateHeaderField(HeaderNames.Path, "/index.html"), - CreateHeaderField(HeaderNames.Scheme, "http"), - CreateHeaderField(HeaderNames.Scheme, "https"), - CreateHeaderField(HeaderNames.Status, "200"), - CreateHeaderField(HeaderNames.Status, "204"), - CreateHeaderField(HeaderNames.Status, "206"), - CreateHeaderField(HeaderNames.Status, "304"), - CreateHeaderField(HeaderNames.Status, "400"), - CreateHeaderField(HeaderNames.Status, "404"), - CreateHeaderField(HeaderNames.Status, "500"), - CreateHeaderField("accept-charset", ""), - CreateHeaderField("accept-encoding", "gzip, deflate"), - CreateHeaderField("accept-language", ""), - CreateHeaderField("accept-ranges", ""), - CreateHeaderField("accept", ""), - CreateHeaderField("access-control-allow-origin", ""), - CreateHeaderField("age", ""), - CreateHeaderField("allow", ""), - CreateHeaderField("authorization", ""), - CreateHeaderField("cache-control", ""), - CreateHeaderField("content-disposition", ""), - CreateHeaderField("content-encoding", ""), - CreateHeaderField("content-language", ""), - CreateHeaderField("content-length", ""), - CreateHeaderField("content-location", ""), - CreateHeaderField("content-range", ""), - CreateHeaderField("content-type", ""), - CreateHeaderField("cookie", ""), - CreateHeaderField("date", ""), - CreateHeaderField("etag", ""), - CreateHeaderField("expect", ""), - CreateHeaderField("expires", ""), - CreateHeaderField("from", ""), - CreateHeaderField("host", ""), - CreateHeaderField("if-match", ""), - CreateHeaderField("if-modified-since", ""), - CreateHeaderField("if-none-match", ""), - CreateHeaderField("if-range", ""), - CreateHeaderField("if-unmodifiedsince", ""), - CreateHeaderField("last-modified", ""), - CreateHeaderField("link", ""), - CreateHeaderField("location", ""), - CreateHeaderField("max-forwards", ""), - CreateHeaderField("proxy-authenticate", ""), - CreateHeaderField("proxy-authorization", ""), - CreateHeaderField("range", ""), - CreateHeaderField("referer", ""), - CreateHeaderField("refresh", ""), - CreateHeaderField("retry-after", ""), - CreateHeaderField("server", ""), - CreateHeaderField("set-cookie", ""), - CreateHeaderField("strict-transport-security", ""), - CreateHeaderField("transfer-encoding", ""), - CreateHeaderField("user-agent", ""), - CreateHeaderField("vary", ""), - CreateHeaderField("via", ""), - CreateHeaderField("www-authenticate", "") - }; - - private static HeaderField CreateHeaderField(string name, string value) - => new HeaderField(Encoding.ASCII.GetBytes(name), Encoding.ASCII.GetBytes(value)); - } -} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs deleted file mode 100644 index e00afa1d28..0000000000 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs +++ /dev/null @@ -1,158 +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. - -using System.Globalization; -using System.Text; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack -{ - internal static class StatusCodes - { - private static readonly byte[] _bytesStatus100 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status100Continue); - private static readonly byte[] _bytesStatus101 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status101SwitchingProtocols); - private static readonly byte[] _bytesStatus102 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status102Processing); - - private static readonly byte[] _bytesStatus200 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status200OK); - private static readonly byte[] _bytesStatus201 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status201Created); - private static readonly byte[] _bytesStatus202 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status202Accepted); - private static readonly byte[] _bytesStatus203 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status203NonAuthoritative); - private static readonly byte[] _bytesStatus204 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status204NoContent); - private static readonly byte[] _bytesStatus205 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status205ResetContent); - private static readonly byte[] _bytesStatus206 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status206PartialContent); - private static readonly byte[] _bytesStatus207 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status207MultiStatus); - private static readonly byte[] _bytesStatus208 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status208AlreadyReported); - private static readonly byte[] _bytesStatus226 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status226IMUsed); - - private static readonly byte[] _bytesStatus300 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status300MultipleChoices); - private static readonly byte[] _bytesStatus301 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status301MovedPermanently); - private static readonly byte[] _bytesStatus302 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status302Found); - private static readonly byte[] _bytesStatus303 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status303SeeOther); - private static readonly byte[] _bytesStatus304 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status304NotModified); - private static readonly byte[] _bytesStatus305 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status305UseProxy); - private static readonly byte[] _bytesStatus306 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status306SwitchProxy); - private static readonly byte[] _bytesStatus307 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status307TemporaryRedirect); - private static readonly byte[] _bytesStatus308 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status308PermanentRedirect); - - private static readonly byte[] _bytesStatus400 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest); - private static readonly byte[] _bytesStatus401 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status401Unauthorized); - private static readonly byte[] _bytesStatus402 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status402PaymentRequired); - private static readonly byte[] _bytesStatus403 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status403Forbidden); - private static readonly byte[] _bytesStatus404 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound); - private static readonly byte[] _bytesStatus405 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status405MethodNotAllowed); - private static readonly byte[] _bytesStatus406 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status406NotAcceptable); - private static readonly byte[] _bytesStatus407 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status407ProxyAuthenticationRequired); - private static readonly byte[] _bytesStatus408 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status408RequestTimeout); - private static readonly byte[] _bytesStatus409 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status409Conflict); - private static readonly byte[] _bytesStatus410 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status410Gone); - private static readonly byte[] _bytesStatus411 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status411LengthRequired); - private static readonly byte[] _bytesStatus412 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status412PreconditionFailed); - private static readonly byte[] _bytesStatus413 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status413PayloadTooLarge); - private static readonly byte[] _bytesStatus414 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status414UriTooLong); - private static readonly byte[] _bytesStatus415 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status415UnsupportedMediaType); - private static readonly byte[] _bytesStatus416 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status416RangeNotSatisfiable); - private static readonly byte[] _bytesStatus417 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status417ExpectationFailed); - private static readonly byte[] _bytesStatus418 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status418ImATeapot); - private static readonly byte[] _bytesStatus419 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status419AuthenticationTimeout); - private static readonly byte[] _bytesStatus421 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status421MisdirectedRequest); - private static readonly byte[] _bytesStatus422 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status422UnprocessableEntity); - private static readonly byte[] _bytesStatus423 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status423Locked); - private static readonly byte[] _bytesStatus424 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status424FailedDependency); - private static readonly byte[] _bytesStatus426 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status426UpgradeRequired); - private static readonly byte[] _bytesStatus428 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status428PreconditionRequired); - private static readonly byte[] _bytesStatus429 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status429TooManyRequests); - private static readonly byte[] _bytesStatus431 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status431RequestHeaderFieldsTooLarge); - private static readonly byte[] _bytesStatus451 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status451UnavailableForLegalReasons); - - private static readonly byte[] _bytesStatus500 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError); - private static readonly byte[] _bytesStatus501 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status501NotImplemented); - private static readonly byte[] _bytesStatus502 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status502BadGateway); - private static readonly byte[] _bytesStatus503 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status503ServiceUnavailable); - private static readonly byte[] _bytesStatus504 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status504GatewayTimeout); - private static readonly byte[] _bytesStatus505 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status505HttpVersionNotsupported); - private static readonly byte[] _bytesStatus506 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status506VariantAlsoNegotiates); - private static readonly byte[] _bytesStatus507 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status507InsufficientStorage); - private static readonly byte[] _bytesStatus508 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status508LoopDetected); - private static readonly byte[] _bytesStatus510 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status510NotExtended); - private static readonly byte[] _bytesStatus511 = CreateStatusBytes(Microsoft.AspNetCore.Http.StatusCodes.Status511NetworkAuthenticationRequired); - - private static byte[] CreateStatusBytes(int statusCode) - { - return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture)); - } - - public static byte[] ToStatusBytes(int statusCode) - { - return statusCode switch - { - Microsoft.AspNetCore.Http.StatusCodes.Status100Continue => _bytesStatus100, - Microsoft.AspNetCore.Http.StatusCodes.Status101SwitchingProtocols => _bytesStatus101, - Microsoft.AspNetCore.Http.StatusCodes.Status102Processing => _bytesStatus102, - - Microsoft.AspNetCore.Http.StatusCodes.Status200OK => _bytesStatus200, - Microsoft.AspNetCore.Http.StatusCodes.Status201Created => _bytesStatus201, - Microsoft.AspNetCore.Http.StatusCodes.Status202Accepted => _bytesStatus202, - Microsoft.AspNetCore.Http.StatusCodes.Status203NonAuthoritative => _bytesStatus203, - Microsoft.AspNetCore.Http.StatusCodes.Status204NoContent => _bytesStatus204, - Microsoft.AspNetCore.Http.StatusCodes.Status205ResetContent => _bytesStatus205, - Microsoft.AspNetCore.Http.StatusCodes.Status206PartialContent => _bytesStatus206, - Microsoft.AspNetCore.Http.StatusCodes.Status207MultiStatus => _bytesStatus207, - Microsoft.AspNetCore.Http.StatusCodes.Status208AlreadyReported => _bytesStatus208, - Microsoft.AspNetCore.Http.StatusCodes.Status226IMUsed => _bytesStatus226, - - Microsoft.AspNetCore.Http.StatusCodes.Status300MultipleChoices => _bytesStatus300, - Microsoft.AspNetCore.Http.StatusCodes.Status301MovedPermanently => _bytesStatus301, - Microsoft.AspNetCore.Http.StatusCodes.Status302Found => _bytesStatus302, - Microsoft.AspNetCore.Http.StatusCodes.Status303SeeOther => _bytesStatus303, - Microsoft.AspNetCore.Http.StatusCodes.Status304NotModified => _bytesStatus304, - Microsoft.AspNetCore.Http.StatusCodes.Status305UseProxy => _bytesStatus305, - Microsoft.AspNetCore.Http.StatusCodes.Status306SwitchProxy => _bytesStatus306, - Microsoft.AspNetCore.Http.StatusCodes.Status307TemporaryRedirect => _bytesStatus307, - Microsoft.AspNetCore.Http.StatusCodes.Status308PermanentRedirect => _bytesStatus308, - - Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest => _bytesStatus400, - Microsoft.AspNetCore.Http.StatusCodes.Status401Unauthorized => _bytesStatus401, - Microsoft.AspNetCore.Http.StatusCodes.Status402PaymentRequired => _bytesStatus402, - Microsoft.AspNetCore.Http.StatusCodes.Status403Forbidden => _bytesStatus403, - Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound => _bytesStatus404, - Microsoft.AspNetCore.Http.StatusCodes.Status405MethodNotAllowed => _bytesStatus405, - Microsoft.AspNetCore.Http.StatusCodes.Status406NotAcceptable => _bytesStatus406, - Microsoft.AspNetCore.Http.StatusCodes.Status407ProxyAuthenticationRequired => _bytesStatus407, - Microsoft.AspNetCore.Http.StatusCodes.Status408RequestTimeout => _bytesStatus408, - Microsoft.AspNetCore.Http.StatusCodes.Status409Conflict => _bytesStatus409, - Microsoft.AspNetCore.Http.StatusCodes.Status410Gone => _bytesStatus410, - Microsoft.AspNetCore.Http.StatusCodes.Status411LengthRequired => _bytesStatus411, - Microsoft.AspNetCore.Http.StatusCodes.Status412PreconditionFailed => _bytesStatus412, - Microsoft.AspNetCore.Http.StatusCodes.Status413PayloadTooLarge => _bytesStatus413, - Microsoft.AspNetCore.Http.StatusCodes.Status414UriTooLong => _bytesStatus414, - Microsoft.AspNetCore.Http.StatusCodes.Status415UnsupportedMediaType => _bytesStatus415, - Microsoft.AspNetCore.Http.StatusCodes.Status416RangeNotSatisfiable => _bytesStatus416, - Microsoft.AspNetCore.Http.StatusCodes.Status417ExpectationFailed => _bytesStatus417, - Microsoft.AspNetCore.Http.StatusCodes.Status418ImATeapot => _bytesStatus418, - Microsoft.AspNetCore.Http.StatusCodes.Status419AuthenticationTimeout => _bytesStatus419, - Microsoft.AspNetCore.Http.StatusCodes.Status421MisdirectedRequest => _bytesStatus421, - Microsoft.AspNetCore.Http.StatusCodes.Status422UnprocessableEntity => _bytesStatus422, - Microsoft.AspNetCore.Http.StatusCodes.Status423Locked => _bytesStatus423, - Microsoft.AspNetCore.Http.StatusCodes.Status424FailedDependency => _bytesStatus424, - Microsoft.AspNetCore.Http.StatusCodes.Status426UpgradeRequired => _bytesStatus426, - Microsoft.AspNetCore.Http.StatusCodes.Status428PreconditionRequired => _bytesStatus428, - Microsoft.AspNetCore.Http.StatusCodes.Status429TooManyRequests => _bytesStatus429, - Microsoft.AspNetCore.Http.StatusCodes.Status431RequestHeaderFieldsTooLarge => _bytesStatus431, - Microsoft.AspNetCore.Http.StatusCodes.Status451UnavailableForLegalReasons => _bytesStatus451, - - Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError => _bytesStatus500, - Microsoft.AspNetCore.Http.StatusCodes.Status501NotImplemented => _bytesStatus501, - Microsoft.AspNetCore.Http.StatusCodes.Status502BadGateway => _bytesStatus502, - Microsoft.AspNetCore.Http.StatusCodes.Status503ServiceUnavailable => _bytesStatus503, - Microsoft.AspNetCore.Http.StatusCodes.Status504GatewayTimeout => _bytesStatus504, - Microsoft.AspNetCore.Http.StatusCodes.Status505HttpVersionNotsupported => _bytesStatus505, - Microsoft.AspNetCore.Http.StatusCodes.Status506VariantAlsoNegotiates => _bytesStatus506, - Microsoft.AspNetCore.Http.StatusCodes.Status507InsufficientStorage => _bytesStatus507, - Microsoft.AspNetCore.Http.StatusCodes.Status508LoopDetected => _bytesStatus508, - Microsoft.AspNetCore.Http.StatusCodes.Status510NotExtended => _bytesStatus510, - Microsoft.AspNetCore.Http.StatusCodes.Status511NetworkAuthenticationRequired => _bytesStatus511, - - _ => CreateStatusBytes(statusCode) - }; - } - } -} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.Generated.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.Generated.cs new file mode 100644 index 0000000000..290fea38f5 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.Generated.cs @@ -0,0 +1,23 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 +{ + internal partial class Http2Connection + { + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + + private static ReadOnlySpan<byte> ClientPrefaceBytes => new byte[24] { (byte)'P', (byte)'R', (byte)'I', (byte)' ', (byte)'*', (byte)' ', (byte)'H', (byte)'T', (byte)'T', (byte)'P', (byte)'/', (byte)'2', (byte)'.', (byte)'0', (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n', (byte)'S', (byte)'M', (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' }; + private static ReadOnlySpan<byte> AuthorityBytes => new byte[10] { (byte)':', (byte)'a', (byte)'u', (byte)'t', (byte)'h', (byte)'o', (byte)'r', (byte)'i', (byte)'t', (byte)'y' }; + private static ReadOnlySpan<byte> MethodBytes => new byte[7] { (byte)':', (byte)'m', (byte)'e', (byte)'t', (byte)'h', (byte)'o', (byte)'d' }; + private static ReadOnlySpan<byte> PathBytes => new byte[5] { (byte)':', (byte)'p', (byte)'a', (byte)'t', (byte)'h' }; + private static ReadOnlySpan<byte> SchemeBytes => new byte[7] { (byte)':', (byte)'s', (byte)'c', (byte)'h', (byte)'e', (byte)'m', (byte)'e' }; + private static ReadOnlySpan<byte> StatusBytes => new byte[7] { (byte)':', (byte)'s', (byte)'t', (byte)'a', (byte)'t', (byte)'u', (byte)'s' }; + private static ReadOnlySpan<byte> ConnectionBytes => new byte[10] { (byte)'c', (byte)'o', (byte)'n', (byte)'n', (byte)'e', (byte)'c', (byte)'t', (byte)'i', (byte)'o', (byte)'n' }; + private static ReadOnlySpan<byte> TeBytes => new byte[2] { (byte)'t', (byte)'e' }; + private static ReadOnlySpan<byte> TrailersBytes => new byte[8] { (byte)'t', (byte)'r', (byte)'a', (byte)'i', (byte)'l', (byte)'e', (byte)'r', (byte)'s' }; + private static ReadOnlySpan<byte> ConnectBytes => new byte[7] { (byte)'C', (byte)'O', (byte)'N', (byte)'N', (byte)'E', (byte)'C', (byte)'T' }; + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 3ccdccef69..339fe5ca08 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -8,6 +8,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Pipelines; +using System.Net.Http; +using System.Net.Http.HPack; using System.Runtime.CompilerServices; using System.Security.Authentication; using System.Text; @@ -19,30 +21,19 @@ using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 { - internal class Http2Connection : IHttp2StreamLifetimeHandler, IHttpHeadersHandler, IRequestProcessor + internal partial class Http2Connection : IHttp2StreamLifetimeHandler, IHttpHeadersHandler, IRequestProcessor { - public static byte[] ClientPreface { get; } = Encoding.ASCII.GetBytes("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"); + public static ReadOnlySpan<byte> ClientPreface => ClientPrefaceBytes; private static readonly PseudoHeaderFields _mandatoryRequestPseudoHeaderFields = PseudoHeaderFields.Method | PseudoHeaderFields.Path | PseudoHeaderFields.Scheme; - private static readonly byte[] _authorityBytes = Encoding.ASCII.GetBytes(HeaderNames.Authority); - private static readonly byte[] _methodBytes = Encoding.ASCII.GetBytes(HeaderNames.Method); - private static readonly byte[] _pathBytes = Encoding.ASCII.GetBytes(HeaderNames.Path); - private static readonly byte[] _schemeBytes = Encoding.ASCII.GetBytes(HeaderNames.Scheme); - private static readonly byte[] _statusBytes = Encoding.ASCII.GetBytes(HeaderNames.Status); - private static readonly byte[] _connectionBytes = Encoding.ASCII.GetBytes("connection"); - private static readonly byte[] _teBytes = Encoding.ASCII.GetBytes("te"); - private static readonly byte[] _trailersBytes = Encoding.ASCII.GetBytes("trailers"); - private static readonly byte[] _connectBytes = Encoding.ASCII.GetBytes("CONNECT"); - private readonly HttpConnectionContext _context; private readonly Http2FrameWriter _frameWriter; private readonly Pipe _input; @@ -204,27 +195,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 while (_isClosed == 0) { var result = await Input.ReadAsync(); - var readableBuffer = result.Buffer; - var consumed = readableBuffer.Start; - var examined = readableBuffer.Start; + var buffer = result.Buffer; // Call UpdateCompletedStreams() prior to frame processing in order to remove any streams that have exceded their drain timeouts. UpdateCompletedStreams(); try { - if (!readableBuffer.IsEmpty) + while (Http2FrameReader.TryReadFrame(ref buffer, _incomingFrame, _serverSettings.MaxFrameSize, out var framePayload)) { - if (Http2FrameReader.ReadFrame(readableBuffer, _incomingFrame, _serverSettings.MaxFrameSize, out var framePayload)) - { - Log.Http2FrameReceived(ConnectionId, _incomingFrame); - consumed = examined = framePayload.End; - await ProcessFrameAsync(application, framePayload); - } - else - { - examined = readableBuffer.End; - } + Log.Http2FrameReceived(ConnectionId, _incomingFrame); + await ProcessFrameAsync(application, framePayload); } if (result.IsCompleted) @@ -242,7 +223,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } finally { - Input.AdvanceTo(consumed, examined); + Input.AdvanceTo(buffer.Start, buffer.End); UpdateConnectionState(); } @@ -913,41 +894,57 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 private void StartStream() { - if (!_isMethodConnect && (_parsedPseudoHeaderFields & _mandatoryRequestPseudoHeaderFields) != _mandatoryRequestPseudoHeaderFields) - { - // All HTTP/2 requests MUST include exactly one valid value for the :method, :scheme, and :path pseudo-header - // fields, unless it is a CONNECT request (Section 8.3). An HTTP request that omits mandatory pseudo-header - // fields is malformed (Section 8.1.2.6). - throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields, Http2ErrorCode.PROTOCOL_ERROR); - } - - if (_clientActiveStreamCount >= _serverSettings.MaxConcurrentStreams) - { - throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMaxStreams, Http2ErrorCode.REFUSED_STREAM); - } - - // We don't use the _serverActiveRequestCount here as during shutdown, it and the dictionary - // counts get out of sync during shutdown. The streams still exist in the dictionary until the client responds with a RST or END_STREAM. - // Also, we care about the dictionary size for too much memory consumption. - if (_streams.Count >= _serverSettings.MaxConcurrentStreams * 2) - { - // Server is getting hit hard with connection resets. - // Tell client to calm down. - // TODO consider making when to send ENHANCE_YOUR_CALM configurable? - throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2TellClientToCalmDown, Http2ErrorCode.ENHANCE_YOUR_CALM); - } - // This must be initialized before we offload the request or else we may start processing request body frames without it. - _currentHeadersStream.InputRemaining = _currentHeadersStream.RequestHeaders.ContentLength; - - // This must wait until we've received all of the headers so we can verify the content-length. - if ((_headerFlags & Http2HeadersFrameFlags.END_STREAM) == Http2HeadersFrameFlags.END_STREAM) - { - _currentHeadersStream.OnEndStreamReceived(); - } - + // The stream now exists and must be tracked and drained even if Http2StreamErrorException is thrown before dispatching to the application. _streams[_incomingFrame.StreamId] = _currentHeadersStream; IncrementActiveClientStreamCount(); _serverActiveStreamCount++; + + try + { + // This must be initialized before we offload the request or else we may start processing request body frames without it. + _currentHeadersStream.InputRemaining = _currentHeadersStream.RequestHeaders.ContentLength; + + // This must wait until we've received all of the headers so we can verify the content-length. + // We also must set the proper EndStream state before rejecting the request for any reason. + if ((_headerFlags & Http2HeadersFrameFlags.END_STREAM) == Http2HeadersFrameFlags.END_STREAM) + { + _currentHeadersStream.OnEndStreamReceived(); + } + + if (!_isMethodConnect && (_parsedPseudoHeaderFields & _mandatoryRequestPseudoHeaderFields) != _mandatoryRequestPseudoHeaderFields) + { + // All HTTP/2 requests MUST include exactly one valid value for the :method, :scheme, and :path pseudo-header + // fields, unless it is a CONNECT request (Section 8.3). An HTTP request that omits mandatory pseudo-header + // fields is malformed (Section 8.1.2.6). + throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields, Http2ErrorCode.PROTOCOL_ERROR); + } + + if (_clientActiveStreamCount > _serverSettings.MaxConcurrentStreams) + { + // The protocol default stream limit is infinite so the client can excede our limit at the start of the connection. + // Refused streams can be retried, by which time the client must have received our settings frame with our limit information. + throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2ErrorMaxStreams, Http2ErrorCode.REFUSED_STREAM); + } + + // We don't use the _serverActiveRequestCount here as during shutdown, it and the dictionary counts get out of sync. + // The streams still exist in the dictionary until the client responds with a RST or END_STREAM. + // Also, we care about the dictionary size for too much memory consumption. + if (_streams.Count > _serverSettings.MaxConcurrentStreams * 2) + { + // Server is getting hit hard with connection resets. + // Tell client to calm down. + // TODO consider making when to send ENHANCE_YOUR_CALM configurable? + throw new Http2StreamErrorException(_currentHeadersStream.StreamId, CoreStrings.Http2TellClientToCalmDown, Http2ErrorCode.ENHANCE_YOUR_CALM); + } + } + catch (Http2StreamErrorException) + { + MakeSpaceInDrainQueue(); + // Tracked for draining + _completedStreams.Enqueue(_currentHeadersStream); + throw; + } + // Must not allow app code to block the connection handling loop. ThreadPool.UnsafeQueueUserWorkItem(_currentHeadersStream, preferLocal: false); } @@ -1044,6 +1041,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } } + // Compare to UpdateCompletedStreams, but only removes streams if over the max stream drain limit. + private void MakeSpaceInDrainQueue() + { + var maxStreams = _serverSettings.MaxConcurrentStreams * 2; + // If we're tracking too many streams, discard the oldest. + while (_streams.Count >= maxStreams && _completedStreams.TryDequeue(out var stream)) + { + if (stream.DrainExpirationTicks == default) + { + _serverActiveStreamCount--; + } + + _streams.Remove(stream.StreamId); + } + } + private void UpdateConnectionState() { if (_isClosed != 0) @@ -1090,7 +1103,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 // We can't throw a Http2StreamErrorException here, it interrupts the header decompression state and may corrupt subsequent header frames on other streams. // For now these either need to be connection errors or BadRequests. If we want to downgrade any of them to stream errors later then we need to // rework the flow so that the remaining headers are drained and the decompression state is maintained. - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { // https://tools.ietf.org/html/rfc7540#section-6.5.2 // "The value is based on the uncompressed size of header fields, including the length of the name and value in octets plus an overhead of 32 octets for each header field."; @@ -1124,10 +1137,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } } - public void OnHeadersComplete() + public void OnHeadersComplete(bool endStream) => _currentHeadersStream.OnHeadersComplete(); - private void ValidateHeader(Span<byte> name, Span<byte> value) + private void ValidateHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { // http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.1 /* @@ -1184,7 +1197,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 if (headerField == PseudoHeaderFields.Method) { - _isMethodConnect = value.SequenceEqual(_connectBytes); + _isMethodConnect = value.SequenceEqual(ConnectBytes); } _parsedPseudoHeaderFields |= headerField; @@ -1217,7 +1230,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } } - private bool IsPseudoHeaderField(Span<byte> name, out PseudoHeaderFields headerField) + private bool IsPseudoHeaderField(ReadOnlySpan<byte> name, out PseudoHeaderFields headerField) { headerField = PseudoHeaderFields.None; @@ -1226,23 +1239,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 return false; } - if (name.SequenceEqual(_pathBytes)) + if (name.SequenceEqual(PathBytes)) { headerField = PseudoHeaderFields.Path; } - else if (name.SequenceEqual(_methodBytes)) + else if (name.SequenceEqual(MethodBytes)) { headerField = PseudoHeaderFields.Method; } - else if (name.SequenceEqual(_schemeBytes)) + else if (name.SequenceEqual(SchemeBytes)) { headerField = PseudoHeaderFields.Scheme; } - else if (name.SequenceEqual(_statusBytes)) + else if (name.SequenceEqual(StatusBytes)) { headerField = PseudoHeaderFields.Status; } - else if (name.SequenceEqual(_authorityBytes)) + else if (name.SequenceEqual(AuthorityBytes)) { headerField = PseudoHeaderFields.Authority; } @@ -1254,9 +1267,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 return true; } - private static bool IsConnectionSpecificHeaderField(Span<byte> name, Span<byte> value) + private static bool IsConnectionSpecificHeaderField(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { - return name.SequenceEqual(_connectionBytes) || (name.SequenceEqual(_teBytes) && !value.SequenceEqual(_trailersBytes)); + return name.SequenceEqual(ConnectionBytes) || (name.SequenceEqual(TeBytes) && !value.SequenceEqual(TrailersBytes)); } private bool TryClose() diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs index 7555b9f223..415dbf3ba2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs @@ -7,13 +7,13 @@ using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.IO.Pipelines; +using System.Net.Http.HPack; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeWriterHelpers; @@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 internal class Http2FrameWriter { // Literal Header Field without Indexing - Indexed Name (Index 8 - :status) + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static private static ReadOnlySpan<byte> ContinueBytes => new byte[] { 0x08, 0x03, (byte)'1', (byte)'0', (byte)'0' }; private readonly object _writeLock = new object(); @@ -239,7 +240,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } } - public ValueTask<FlushResult> WriteDataAsync(int streamId, StreamOutputFlowControl flowControl, in ReadOnlySequence<byte> data, bool endStream) + public ValueTask<FlushResult> WriteDataAsync(int streamId, StreamOutputFlowControl flowControl, in ReadOnlySequence<byte> data, bool endStream, bool forceFlush) { // The Length property of a ReadOnlySequence can be expensive, so we cache the value. var dataLength = data.Length; @@ -261,7 +262,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 // This cast is safe since if dataLength would overflow an int, it's guaranteed to be greater than the available flow control window. flowControl.Advance((int)dataLength); WriteDataUnsynchronized(streamId, data, dataLength, endStream); - return TimeFlushUnsynchronizedAsync(); + + if (forceFlush) + { + return TimeFlushUnsynchronizedAsync(); + } + + return default; } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs index 18adcc1a82..3bd9794e47 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs @@ -380,7 +380,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 // Write any remaining content then write trailers if (readResult.Buffer.Length > 0) { - flushResult = await _frameWriter.WriteDataAsync(_streamId, _flowControl, readResult.Buffer, endStream: false); + // Only flush if required (i.e. content length exceeds flow control availability) + // Writing remaining content without flushing allows content and trailers to be sent in the same packet + await _frameWriter.WriteDataAsync(_streamId, _flowControl, readResult.Buffer, endStream: false, forceFlush: false); } _stream.ResponseTrailers.SetReadOnly(); @@ -404,7 +406,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 { _stream.DecrementActiveClientStreamCount(); } - flushResult = await _frameWriter.WriteDataAsync(_streamId, _flowControl, readResult.Buffer, endStream); + flushResult = await _frameWriter.WriteDataAsync(_streamId, _flowControl, readResult.Buffer, endStream, forceFlush: true); } _pipeReader.AdvanceTo(readResult.Buffer.End); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3ErrorCode.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3ErrorCode.cs new file mode 100644 index 0000000000..ac01a35477 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3ErrorCode.cs @@ -0,0 +1,101 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal enum Http3ErrorCode : uint + { + /// <summary> + /// HTTP_NO_ERROR (0x100): + /// No error. This is used when the connection or stream needs to be closed, but there is no error to signal. + /// </summary> + NoError = 0x100, + /// <summary> + /// HTTP_GENERAL_PROTOCOL_ERROR (0x101): + /// Peer violated protocol requirements in a way which doesn’t match a more specific error code, + /// or endpoint declines to use the more specific error code. + /// </summary> + ProtocolError = 0x101, + /// <summary> + /// HTTP_INTERNAL_ERROR (0x102): + /// An internal error has occurred in the HTTP stack. + /// </summary> + InternalError = 0x102, + /// <summary> + /// HTTP_STREAM_CREATION_ERROR (0x103): + /// The endpoint detected that its peer created a stream that it will not accept. + /// </summary> + StreamCreationError = 0x103, + /// <summary> + /// HTTP_CLOSED_CRITICAL_STREAM (0x104): + /// A stream required by the connection was closed or reset. + /// </summary> + ClosedCriticalStream = 0x104, + /// <summary> + /// HTTP_UNEXPECTED_FRAME (0x105): + /// A frame was received which was not permitted in the current state. + /// </summary> + UnexpectedFrame = 0x105, + /// <summary> + /// HTTP_FRAME_ERROR (0x106): + /// A frame that fails to satisfy layout requirements or with an invalid size was received. + /// </summary> + FrameError = 0x106, + /// <summary> + /// HTTP_EXCESSIVE_LOAD (0x107): + /// The endpoint detected that its peer is exhibiting a behavior that might be generating excessive load. + /// </summary> + ExcessiveLoad = 0x107, + /// <summary> + /// HTTP_WRONG_STREAM (0x108): + /// A frame was received on a stream where it is not permitted. + /// </summary> + WrongStream = 0x108, + /// <summary> + /// HTTP_ID_ERROR (0x109): + /// A Stream ID, Push ID, or Placeholder ID was used incorrectly, such as exceeding a limit, reducing a limit, or being reused. + /// </summary> + IdError = 0x109, + /// <summary> + /// HTTP_SETTINGS_ERROR (0x10A): + /// An endpoint detected an error in the payload of a SETTINGS frame: a duplicate setting was detected, + /// a client-only setting was sent by a server, or a server-only setting by a client. + /// </summary> + SettingsError = 0x10a, + /// <summary> + /// HTTP_MISSING_SETTINGS (0x10B): + /// No SETTINGS frame was received at the beginning of the control stream. + /// </summary> + MissingSettings = 0x10b, + /// <summary> + /// HTTP_REQUEST_REJECTED (0x10C): + /// A server rejected a request without performing any application processing. + /// </summary> + RequestRejected = 0x10c, + /// <summary> + /// HTTP_REQUEST_CANCELLED (0x10D): + /// The request or its response (including pushed response) is cancelled. + /// </summary> + RequestCancelled = 0x10d, + /// <summary> + /// HTTP_REQUEST_INCOMPLETE (0x10E): + /// The client’s stream terminated without containing a fully-formed request. + /// </summary> + RequestIncomplete = 0x10e, + /// <summary> + /// HTTP_EARLY_RESPONSE (0x10F): + /// The remainder of the client’s request is not needed to produce a response. For use in STOP_SENDING only. + /// </summary> + EarlyResponse = 0x10f, + /// <summary> + /// HTTP_CONNECT_ERROR (0x110): + /// The connection established in response to a CONNECT request was reset or abnormally closed. + /// </summary> + ConnectError = 0x110, + /// <summary> + /// HTTP_VERSION_FALLBACK (0x111): + /// The requested operation cannot be served over HTTP/3. The peer should retry over HTTP/1.1. + /// </summary> + VersionFallback = 0x111, + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HuffmanDecodingException.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Data.cs similarity index 61% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HuffmanDecodingException.cs rename to src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Data.cs index f20769f0b6..536147b1fb 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HuffmanDecodingException.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Data.cs @@ -1,15 +1,14 @@ // 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; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 { - internal sealed class HuffmanDecodingException : Exception + internal partial class Http3Frame { - public HuffmanDecodingException(string message) - : base(message) + public void PrepareData() { + Length = 0; + Type = Http3FrameType.Data; } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.GoAway.cs similarity index 60% rename from src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs rename to src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.GoAway.cs index 0ed16148b8..a1984d93fb 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/IHttpHeadersHandler.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.GoAway.cs @@ -1,13 +1,14 @@ // 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; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 { - public interface IHttpHeadersHandler + internal partial class Http3Frame { - void OnHeader(Span<byte> name, Span<byte> value); - void OnHeadersComplete(); + public void PrepareGoAway() + { + Length = 0; + Type = Http3FrameType.GoAway; + } } -} \ No newline at end of file +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Headers.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Headers.cs new file mode 100644 index 0000000000..bc582d13bb --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Headers.cs @@ -0,0 +1,14 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal partial class Http3Frame + { + public void PrepareHeaders() + { + Length = 0; + Type = Http3FrameType.Headers; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Settings.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Settings.cs new file mode 100644 index 0000000000..1d06d5e403 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.Settings.cs @@ -0,0 +1,14 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal partial class Http3Frame + { + public void PrepareSettings() + { + Length = 0; + Type = Http3FrameType.Settings; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.cs new file mode 100644 index 0000000000..a7dff3a0a1 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3Frame.cs @@ -0,0 +1,17 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal partial class Http3Frame + { + public long Length { get; set; } + + public Http3FrameType Type { get; internal set; } + + public override string ToString() + { + return $"{Type} Length: {Length}"; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3FrameType.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3FrameType.cs new file mode 100644 index 0000000000..c690567b06 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Frames/Http3FrameType.cs @@ -0,0 +1,17 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal enum Http3FrameType + { + Data = 0x0, + Headers = 0x1, + CancelPush = 0x3, + Settings = 0x4, + PushPromise = 0x5, + GoAway = 0x7, + MaxPushId = 0xD, + DuplicatePush = 0xE + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Helpers/VariableLengthIntegerHelper.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Helpers/VariableLengthIntegerHelper.cs new file mode 100644 index 0000000000..c63c908ab9 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Helpers/VariableLengthIntegerHelper.cs @@ -0,0 +1,115 @@ +// 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.Buffers.Binary; +using System.Diagnostics; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + /// <summary> + /// Variable length integer encoding and decoding methods. Based on https://tools.ietf.org/html/draft-ietf-quic-transport-24#section-16. + /// Either will take up 1, 2, 4, or 8 bytes. + /// </summary> + internal static class VariableLengthIntegerHelper + { + private const int TwoByteSubtract = 0x4000; + private const uint FourByteSubtract = 0x80000000; + private const ulong EightByteSubtract = 0xC000000000000000; + private const int OneByteLimit = 64; + private const int TwoByteLimit = 16383; + private const int FourByteLimit = 1073741823; + + public static long GetInteger(in ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined) + { + consumed = buffer.Start; + examined = buffer.End; + + if (buffer.Length == 0) + { + return -1; + } + + // The first two bits of the first byte represent the length of the + // variable length integer + // 00 = length 1 + // 01 = length 2 + // 10 = length 4 + // 11 = length 8 + + var span = buffer.Slice(0, Math.Min(buffer.Length, 8)).ToSpan(); + + var firstByte = span[0]; + + if ((firstByte & 0xC0) == 0) + { + consumed = examined = buffer.GetPosition(1); + return firstByte & 0x3F; + } + else if ((firstByte & 0xC0) == 0x40) + { + if (span.Length < 2) + { + return -1; + } + + consumed = examined = buffer.GetPosition(2); + + return BinaryPrimitives.ReadUInt16BigEndian(span) - TwoByteSubtract; + } + else if ((firstByte & 0xC0) == 0x80) + { + if (span.Length < 4) + { + return -1; + } + + consumed = examined = buffer.GetPosition(4); + + return BinaryPrimitives.ReadUInt32BigEndian(span) - FourByteSubtract; + } + else + { + if (span.Length < 8) + { + return -1; + } + + consumed = examined = buffer.GetPosition(8); + + return (long)(BinaryPrimitives.ReadUInt64BigEndian(span) - EightByteSubtract); + } + } + + public static int WriteInteger(Span<byte> buffer, long longToEncode) + { + Debug.Assert(buffer.Length >= 8); + Debug.Assert(longToEncode < long.MaxValue / 2); + + if (longToEncode < OneByteLimit) + { + buffer[0] = (byte)longToEncode; + return 1; + } + else if (longToEncode < TwoByteLimit) + { + BinaryPrimitives.WriteUInt16BigEndian(buffer, (ushort)longToEncode); + buffer[0] += 0x40; + return 2; + } + else if (longToEncode < FourByteLimit) + { + BinaryPrimitives.WriteUInt32BigEndian(buffer, (uint)longToEncode); + buffer[0] += 0x80; + return 4; + } + else + { + BinaryPrimitives.WriteUInt64BigEndian(buffer, (ulong)longToEncode); + buffer[0] += 0xC0; + return 8; + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs new file mode 100644 index 0000000000..ca0ac6bc49 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Connection.cs @@ -0,0 +1,206 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Concurrent; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Abstractions.Features; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal class Http3Connection : IRequestProcessor + { + public HttpConnectionContext Context { get; private set; } + + public DynamicTable DynamicTable { get; set; } + + public Http3ControlStream SettingsStream { get; set; } + public Http3ControlStream EncoderStream { get; set; } + public Http3ControlStream DecoderStream { get; set; } + + private readonly ConcurrentDictionary<long, Http3Stream> _streams = new ConcurrentDictionary<long, Http3Stream>(); + + // To be used by GO_AWAY + private long _highestOpenedStreamId; // TODO lock to access + //private volatile bool _haveSentGoAway; + + public Http3Connection(HttpConnectionContext context) + { + Context = context; + DynamicTable = new DynamicTable(0); + } + + internal long HighestStreamId + { + get + { + return _highestOpenedStreamId; + } + set + { + if (_highestOpenedStreamId < value) + { + _highestOpenedStreamId = value; + } + } + } + + public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> application) + { + var streamListenerFeature = Context.ConnectionFeatures.Get<IQuicStreamListenerFeature>(); + + // Start other three unidirectional streams here. + var settingsStream = CreateSettingsStream(application); + var encoderStream = CreateEncoderStream(application); + var decoderStream = CreateDecoderStream(application); + + try + { + while (true) + { + var connectionContext = await streamListenerFeature.AcceptAsync(); + if (connectionContext == null) + { + break; + } + + //if (_haveSentGoAway) + //{ + // // error here. + //} + + var httpConnectionContext = new HttpConnectionContext + { + ConnectionId = connectionContext.ConnectionId, + ConnectionContext = connectionContext, + Protocols = Context.Protocols, + ServiceContext = Context.ServiceContext, + ConnectionFeatures = connectionContext.Features, + MemoryPool = Context.MemoryPool, + Transport = connectionContext.Transport, + TimeoutControl = Context.TimeoutControl, + LocalEndPoint = connectionContext.LocalEndPoint as IPEndPoint, + RemoteEndPoint = connectionContext.RemoteEndPoint as IPEndPoint + }; + + var streamFeature = httpConnectionContext.ConnectionFeatures.Get<IQuicStreamFeature>(); + var streamId = streamFeature.StreamId; + HighestStreamId = streamId; + + if (streamFeature.IsUnidirectional) + { + var stream = new Http3ControlStream<TContext>(application, this, httpConnectionContext); + ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false); + } + else + { + var http3Stream = new Http3Stream<TContext>(application, this, httpConnectionContext); + var stream = http3Stream; + _streams[streamId] = http3Stream; + ThreadPool.UnsafeQueueUserWorkItem(stream, preferLocal: false); + } + } + } + finally + { + await settingsStream; + await encoderStream; + await decoderStream; + foreach (var stream in _streams.Values) + { + stream.Abort(new ConnectionAbortedException("")); + } + } + } + + private async ValueTask CreateSettingsStream<TContext>(IHttpApplication<TContext> application) + { + var stream = await CreateNewUnidirectionalStreamAsync(application); + SettingsStream = stream; + await stream.SendStreamIdAsync(id: 0); + await stream.SendSettingsFrameAsync(); + } + + private async ValueTask CreateEncoderStream<TContext>(IHttpApplication<TContext> application) + { + var stream = await CreateNewUnidirectionalStreamAsync(application); + EncoderStream = stream; + await stream.SendStreamIdAsync(id: 2); + } + + private async ValueTask CreateDecoderStream<TContext>(IHttpApplication<TContext> application) + { + var stream = await CreateNewUnidirectionalStreamAsync(application); + DecoderStream = stream; + await stream.SendStreamIdAsync(id: 3); + } + + private async ValueTask<Http3ControlStream> CreateNewUnidirectionalStreamAsync<TContext>(IHttpApplication<TContext> application) + { + var connectionContext = await Context.ConnectionFeatures.Get<IQuicCreateStreamFeature>().StartUnidirectionalStreamAsync(); + var httpConnectionContext = new HttpConnectionContext + { + ConnectionId = connectionContext.ConnectionId, + ConnectionContext = connectionContext, + Protocols = Context.Protocols, + ServiceContext = Context.ServiceContext, + ConnectionFeatures = connectionContext.Features, + MemoryPool = Context.MemoryPool, + Transport = connectionContext.Transport, + TimeoutControl = Context.TimeoutControl, + LocalEndPoint = connectionContext.LocalEndPoint as IPEndPoint, + RemoteEndPoint = connectionContext.RemoteEndPoint as IPEndPoint + }; + + return new Http3ControlStream<TContext>(application, this, httpConnectionContext); + } + + public void StopProcessingNextRequest() + { + } + + public void HandleRequestHeadersTimeout() + { + } + + public void HandleReadDataRateTimeout() + { + } + + public void OnInputOrOutputCompleted() + { + } + + public void Tick(DateTimeOffset now) + { + } + + public void Abort(ConnectionAbortedException ex) + { + // Send goaway + // Abort currently active streams + // TODO need to figure out if there is server initiated connection close rather than stream close? + } + + public void ApplyMaxHeaderListSize(long value) + { + // TODO something here to call OnHeader? + } + + internal void ApplyBlockedStream(long value) + { + } + + internal void ApplyMaxTableCapacity(long value) + { + // TODO make sure this works + //_maxDynamicTableSize = value; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ConnectionException.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ConnectionException.cs new file mode 100644 index 0000000000..c410c34a3f --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ConnectionException.cs @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.Serialization; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal +{ + [Serializable] + internal class Http3ConnectionException : Exception + { + public Http3ConnectionException() + { + } + + public Http3ConnectionException(string message) : base(message) + { + } + + public Http3ConnectionException(string message, Exception innerException) : base(message, innerException) + { + } + + protected Http3ConnectionException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs new file mode 100644 index 0000000000..8163d65161 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStream.cs @@ -0,0 +1,388 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal abstract class Http3ControlStream : IThreadPoolWorkItem + { + private const int ControlStream = 0; + private const int EncoderStream = 2; + private const int DecoderStream = 3; + private Http3FrameWriter _frameWriter; + private readonly Http3Connection _http3Connection; + private HttpConnectionContext _context; + private readonly Http3Frame _incomingFrame = new Http3Frame(); + private volatile int _isClosed; + private int _gracefulCloseInitiator; + + private bool _haveReceivedSettingsFrame; + + public Http3ControlStream(Http3Connection http3Connection, HttpConnectionContext context) + { + var httpLimits = context.ServiceContext.ServerOptions.Limits; + + _http3Connection = http3Connection; + _context = context; + + _frameWriter = new Http3FrameWriter( + context.Transport.Output, + context.ConnectionContext, + context.TimeoutControl, + httpLimits.MinResponseDataRate, + context.ConnectionId, + context.MemoryPool, + context.ServiceContext.Log); + } + + private void OnStreamClosed() + { + Abort(new ConnectionAbortedException("HTTP_CLOSED_CRITICAL_STREAM")); + } + + public PipeReader Input => _context.Transport.Input; + + + public void Abort(ConnectionAbortedException ex) + { + } + + public void HandleReadDataRateTimeout() + { + //Log.RequestBodyMinimumDataRateNotSatisfied(ConnectionId, null, Limits.MinRequestBodyDataRate.BytesPerSecond); + Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestBodyTimeout)); + } + + public void HandleRequestHeadersTimeout() + { + //Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout)); + Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout)); + } + + public void OnInputOrOutputCompleted() + { + TryClose(); + _frameWriter.Abort(new ConnectionAbortedException(CoreStrings.ConnectionAbortedByClient)); + } + + private bool TryClose() + { + if (Interlocked.Exchange(ref _isClosed, 1) == 0) + { + return true; + } + + // TODO make this actually close the Http3Stream by telling msquic to close the stream. + return false; + } + + private async ValueTask HandleEncodingTask() + { + var encoder = new EncoderStreamReader(10000); // TODO get value from limits + while (_isClosed == 0) + { + var result = await Input.ReadAsync(); + var readableBuffer = result.Buffer; + if (!readableBuffer.IsEmpty) + { + // This should always read all bytes in the input no matter what. + encoder.Read(readableBuffer); + } + Input.AdvanceTo(readableBuffer.End); + } + } + + private async ValueTask HandleDecodingTask() + { + var decoder = new DecoderStreamReader(); + while (_isClosed == 0) + { + var result = await Input.ReadAsync(); + var readableBuffer = result.Buffer; + var consumed = readableBuffer.Start; + var examined = readableBuffer.Start; + if (!readableBuffer.IsEmpty) + { + decoder.Read(readableBuffer); + } + Input.AdvanceTo(readableBuffer.End); + } + } + + internal async ValueTask SendStreamIdAsync(int id) + { + await _frameWriter.WriteStreamIdAsync(id); + } + + internal async ValueTask SendSettingsFrameAsync() + { + await _frameWriter.WriteSettingsAsync(null); + } + + private async ValueTask<long> TryReadStreamIdAsync() + { + while (_isClosed == 0) + { + var result = await Input.ReadAsync(); + var readableBuffer = result.Buffer; + var consumed = readableBuffer.Start; + var examined = readableBuffer.End; + + try + { + if (!readableBuffer.IsEmpty) + { + var id = VariableLengthIntegerHelper.GetInteger(readableBuffer, out consumed, out examined); + if (id != -1) + { + return id; + } + } + + if (result.IsCompleted) + { + return -1; + } + } + finally + { + Input.AdvanceTo(consumed, examined); + } + } + + return -1; + } + + public async Task ProcessRequestAsync<TContext>(IHttpApplication<TContext> application) + { + var streamType = await TryReadStreamIdAsync(); + + if (streamType == -1) + { + return; + } + + if (streamType == ControlStream) + { + if (_http3Connection.SettingsStream != null) + { + throw new Http3ConnectionException("HTTP_STREAM_CREATION_ERROR"); + } + + await HandleControlStream(); + } + else if (streamType == EncoderStream) + { + if (_http3Connection.EncoderStream != null) + { + throw new Http3ConnectionException("HTTP_STREAM_CREATION_ERROR"); + } + await HandleEncodingTask(); + return; + } + else if (streamType == DecoderStream) + { + if (_http3Connection.DecoderStream != null) + { + throw new Http3ConnectionException("HTTP_STREAM_CREATION_ERROR"); + } + await HandleDecodingTask(); + } + else + { + // TODO Close the control stream as it's unexpected. + } + return; + } + + private async Task HandleControlStream() + { + while (_isClosed == 0) + { + var result = await Input.ReadAsync(); + var readableBuffer = result.Buffer; + var consumed = readableBuffer.Start; + var examined = readableBuffer.End; + + try + { + if (!readableBuffer.IsEmpty) + { + // need to kick off httpprotocol process request async here. + while (Http3FrameReader.TryReadFrame(ref readableBuffer, _incomingFrame, 16 * 1024, out var framePayload)) + { + //Log.Http2FrameReceived(ConnectionId, _incomingFrame); + consumed = examined = framePayload.End; + await ProcessHttp3ControlStream(framePayload); + } + } + + if (result.IsCompleted) + { + return; + } + } + catch (Http3StreamErrorException) + { + } + finally + { + Input.AdvanceTo(consumed, examined); + } + } + } + + private ValueTask ProcessHttp3ControlStream(in ReadOnlySequence<byte> payload) + { + // Two things: + // settings must be sent as the first frame of each control stream by each peer + // Can't send more than two settings frames. + switch (_incomingFrame.Type) + { + case Http3FrameType.Data: + case Http3FrameType.Headers: + case Http3FrameType.DuplicatePush: + case Http3FrameType.PushPromise: + throw new Http3ConnectionException("HTTP_FRAME_UNEXPECTED"); + case Http3FrameType.Settings: + return ProcessSettingsFrameAsync(payload); + case Http3FrameType.GoAway: + return ProcessGoAwayFrameAsync(); + case Http3FrameType.CancelPush: + return ProcessCancelPushFrameAsync(); + case Http3FrameType.MaxPushId: + return ProcessMaxPushIdFrameAsync(); + default: + return ProcessUnknownFrameAsync(); + } + } + + private ValueTask ProcessSettingsFrameAsync(ReadOnlySequence<byte> payload) + { + if (_haveReceivedSettingsFrame) + { + throw new Http3ConnectionException("H3_SETTINGS_ERROR"); + } + + _haveReceivedSettingsFrame = true; + using var closedRegistration = _context.ConnectionContext.ConnectionClosed.Register(state => ((Http3ControlStream)state).OnStreamClosed(), this); + + while (true) + { + var id = VariableLengthIntegerHelper.GetInteger(payload, out var consumed, out var examinded); + if (id == -1) + { + break; + } + + payload = payload.Slice(consumed); + + var value = VariableLengthIntegerHelper.GetInteger(payload, out consumed, out examinded); + if (id == -1) + { + break; + } + + payload = payload.Slice(consumed); + ProcessSetting(id, value); + } + + return default; + } + + private void ProcessSetting(long id, long value) + { + // These are client settings, for outbound traffic. + switch (id) + { + case (long)Http3SettingType.QPackMaxTableCapacity: + _http3Connection.ApplyMaxTableCapacity(value); + break; + case (long)Http3SettingType.MaxHeaderListSize: + _http3Connection.ApplyMaxHeaderListSize(value); + break; + case (long)Http3SettingType.QPackBlockedStreams: + _http3Connection.ApplyBlockedStream(value); + break; + default: + // Ignore all unknown settings. + break; + } + } + + private ValueTask ProcessGoAwayFrameAsync() + { + if (!_haveReceivedSettingsFrame) + { + throw new Http3ConnectionException("HTTP_FRAME_UNEXPECTED"); + } + // Get highest stream id and write that to the response. + return default; + } + + private ValueTask ProcessCancelPushFrameAsync() + { + if (!_haveReceivedSettingsFrame) + { + throw new Http3ConnectionException("HTTP_FRAME_UNEXPECTED"); + } + // This should just noop. + return default; + } + + private ValueTask ProcessMaxPushIdFrameAsync() + { + if (!_haveReceivedSettingsFrame) + { + throw new Http3ConnectionException("HTTP_FRAME_UNEXPECTED"); + } + return default; + } + + private ValueTask ProcessUnknownFrameAsync() + { + if (!_haveReceivedSettingsFrame) + { + throw new Http3ConnectionException("HTTP_FRAME_UNEXPECTED"); + } + return default; + } + + public void StopProcessingNextRequest() + => StopProcessingNextRequest(serverInitiated: true); + + public void StopProcessingNextRequest(bool serverInitiated) + { + var initiator = serverInitiated ? GracefulCloseInitiator.Server : GracefulCloseInitiator.Client; + + if (Interlocked.CompareExchange(ref _gracefulCloseInitiator, initiator, GracefulCloseInitiator.None) == GracefulCloseInitiator.None) + { + Input.CancelPendingRead(); + } + } + + public void Tick(DateTimeOffset now) + { + } + + /// <summary> + /// Used to kick off the request processing loop by derived classes. + /// </summary> + public abstract void Execute(); + + private static class GracefulCloseInitiator + { + public const int None = 0; + public const int Server = 1; + public const int Client = 2; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStreamOfT.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStreamOfT.cs new file mode 100644 index 0000000000..880f0f4c1b --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3ControlStreamOfT.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Abstractions; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal sealed class Http3ControlStream<TContext> : Http3ControlStream, IHostContextContainer<TContext> + { + private readonly IHttpApplication<TContext> _application; + + public Http3ControlStream(IHttpApplication<TContext> application, Http3Connection connection, HttpConnectionContext context) : base(connection, context) + { + _application = application; + } + + public override void Execute() + { + _ = ProcessRequestAsync(_application); + } + + // Pooled Host context + TContext IHostContextContainer<TContext>.HostContext { get; set; } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameReader.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameReader.cs new file mode 100644 index 0000000000..020006ae27 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameReader.cs @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Buffers; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal class Http3FrameReader + { + /* https://quicwg.org/base-drafts/draft-ietf-quic-http.html#frame-layout + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Type (i) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Length (i) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Frame Payload (*) ... + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + internal static bool TryReadFrame(ref ReadOnlySequence<byte> readableBuffer, Http3Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload) + { + framePayload = ReadOnlySequence<byte>.Empty; + var consumed = readableBuffer.Start; + var examined = readableBuffer.Start; + + var type = VariableLengthIntegerHelper.GetInteger(readableBuffer, out consumed, out examined); + if (type == -1) + { + return false; + } + + var firstLengthBuffer = readableBuffer.Slice(consumed); + + var length = VariableLengthIntegerHelper.GetInteger(firstLengthBuffer, out consumed, out examined); + + // Make sure the whole frame is buffered + if (length == -1) + { + return false; + } + + var startOfFramePayload = readableBuffer.Slice(consumed); + if (startOfFramePayload.Length < length) + { + return false; + } + + frame.Length = length; + frame.Type = (Http3FrameType)type; + + // The remaining payload minus the extra fields + framePayload = startOfFramePayload.Slice(0, length); + readableBuffer = readableBuffer.Slice(framePayload.End); + + return true; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs new file mode 100644 index 0000000000..f7905fdd76 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3FrameWriter.cs @@ -0,0 +1,326 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.IO.Pipelines; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeWriterHelpers; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal class Http3FrameWriter + { + private readonly object _writeLock = new object(); + private readonly QPackEncoder _qpackEncoder = new QPackEncoder(); + + private readonly PipeWriter _outputWriter; + private readonly ConnectionContext _connectionContext; + private readonly ITimeoutControl _timeoutControl; + private readonly MinDataRate _minResponseDataRate; + private readonly MemoryPool<byte> _memoryPool; + private readonly IKestrelTrace _log; + private readonly Http3Frame _outgoingFrame; + private readonly TimingPipeFlusher _flusher; + + // TODO update max frame size + private uint _maxFrameSize = 10000; //Http3PeerSettings.MinAllowedMaxFrameSize; + private byte[] _headerEncodingBuffer; + + private long _unflushedBytes; + private bool _completed; + private bool _aborted; + + //private int _unflushedBytes; + + public Http3FrameWriter(PipeWriter output, ConnectionContext connectionContext, ITimeoutControl timeoutControl, MinDataRate minResponseDataRate, string connectionId, MemoryPool<byte> memoryPool, IKestrelTrace log) + { + _outputWriter = output; + _connectionContext = connectionContext; + _timeoutControl = timeoutControl; + _minResponseDataRate = minResponseDataRate; + _memoryPool = memoryPool; + _log = log; + _outgoingFrame = new Http3Frame(); + _flusher = new TimingPipeFlusher(_outputWriter, timeoutControl, log); + _headerEncodingBuffer = new byte[_maxFrameSize]; + } + + public void UpdateMaxFrameSize(uint maxFrameSize) + { + lock (_writeLock) + { + if (_maxFrameSize != maxFrameSize) + { + _maxFrameSize = maxFrameSize; + _headerEncodingBuffer = new byte[_maxFrameSize]; + } + } + } + + // TODO actually write settings here. + internal Task WriteSettingsAsync(IList<Http3PeerSettings> settings) + { + _outgoingFrame.PrepareSettings(); + var buffer = _outputWriter.GetSpan(2); + + buffer[0] = (byte)_outgoingFrame.Type; + buffer[1] = 0; + + _outputWriter.Advance(2); + + return _outputWriter.FlushAsync().AsTask(); + } + + internal Task WriteStreamIdAsync(long id) + { + var buffer = _outputWriter.GetSpan(8); + _outputWriter.Advance(VariableLengthIntegerHelper.WriteInteger(buffer, id)); + return _outputWriter.FlushAsync().AsTask(); + } + + public ValueTask<FlushResult> WriteDataAsync(in ReadOnlySequence<byte> data) + { + // The Length property of a ReadOnlySequence can be expensive, so we cache the value. + var dataLength = data.Length; + + lock (_writeLock) + { + if (_completed) + { + return default; + } + + WriteDataUnsynchronized(data, dataLength); + return TimeFlushUnsynchronizedAsync(); + } + } + + private void WriteDataUnsynchronized(in ReadOnlySequence<byte> data, long dataLength) + { + Debug.Assert(dataLength == data.Length); + + _outgoingFrame.PrepareData(); + + if (dataLength > _maxFrameSize) + { + SplitAndWriteDataUnsynchronized(in data, dataLength); + return; + } + + _outgoingFrame.Length = (int)dataLength; + + WriteHeaderUnsynchronized(); + + foreach (var buffer in data) + { + _outputWriter.Write(buffer.Span); + } + + return; + + void SplitAndWriteDataUnsynchronized(in ReadOnlySequence<byte> data, long dataLength) + { + Debug.Assert(dataLength == data.Length); + + var dataPayloadLength = (int)_maxFrameSize; + + Debug.Assert(dataLength > dataPayloadLength); + + var remainingData = data; + do + { + var currentData = remainingData.Slice(0, dataPayloadLength); + _outgoingFrame.Length = dataPayloadLength; + + WriteHeaderUnsynchronized(); + + foreach (var buffer in currentData) + { + _outputWriter.Write(buffer.Span); + } + + dataLength -= dataPayloadLength; + remainingData = remainingData.Slice(dataPayloadLength); + + } while (dataLength > dataPayloadLength); + + _outgoingFrame.Length = (int)dataLength; + + WriteHeaderUnsynchronized(); + + foreach (var buffer in remainingData) + { + _outputWriter.Write(buffer.Span); + } + } + } + + private void WriteHeaderUnsynchronized() + { + var headerLength = WriteHeader(_outgoingFrame, _outputWriter); + + // We assume the payload will be written prior to the next flush. + _unflushedBytes += headerLength + _outgoingFrame.Length; + } + + internal static int WriteHeader(Http3Frame frame, PipeWriter output) + { + // max size of the header is 16, most likely it will be smaller. + var buffer = output.GetSpan(16); + + var typeLength = VariableLengthIntegerHelper.WriteInteger(buffer, (int)frame.Type); + + buffer = buffer.Slice(typeLength); + + var lengthLength = VariableLengthIntegerHelper.WriteInteger(buffer, (int)frame.Length); + + var totalLength = typeLength + lengthLength; + output.Advance(typeLength + lengthLength); + + return totalLength; + } + + public ValueTask<FlushResult> WriteResponseTrailers(int streamId, HttpResponseTrailers headers) + { + lock (_writeLock) + { + if (_completed) + { + return default; + } + + try + { + _outgoingFrame.PrepareHeaders(); + var buffer = _headerEncodingBuffer.AsSpan(); + var done = _qpackEncoder.BeginEncode(EnumerateHeaders(headers), buffer, out var payloadLength); + FinishWritingHeaders(streamId, payloadLength, done); + } + catch (QPackEncodingException) + { + //_log.HPackEncodingError(_connectionId, streamId, hex); + //_http3Stream.Abort(new ConnectionAbortedException(hex.Message, hex)); + } + + return TimeFlushUnsynchronizedAsync(); + } + } + + private ValueTask<FlushResult> TimeFlushUnsynchronizedAsync() + { + var bytesWritten = _unflushedBytes; + _unflushedBytes = 0; + + return _flusher.FlushAsync(_minResponseDataRate, bytesWritten); + } + + public ValueTask<FlushResult> FlushAsync(IHttpOutputAborter outputAborter, CancellationToken cancellationToken) + { + lock (_writeLock) + { + if (_completed) + { + return default; + } + + var bytesWritten = _unflushedBytes; + _unflushedBytes = 0; + + return _flusher.FlushAsync(_minResponseDataRate, bytesWritten, outputAborter, cancellationToken); + } + } + + internal void WriteResponseHeaders(int streamId, int statusCode, IHeaderDictionary headers) + { + lock (_writeLock) + { + if (_completed) + { + return; + } + + try + { + _outgoingFrame.PrepareHeaders(); + var buffer = _headerEncodingBuffer.AsSpan(); + var done = _qpackEncoder.BeginEncode(statusCode, EnumerateHeaders(headers), buffer, out var payloadLength); + FinishWritingHeaders(streamId, payloadLength, done); + } + catch (QPackEncodingException hex) + { + // TODO figure out how to abort the stream here. + //_http3Stream.Abort(new ConnectionAbortedException(hex.Message, hex)); + throw new InvalidOperationException(hex.Message, hex); // Report the error to the user if this was the first write. + } + } + } + + private void FinishWritingHeaders(int streamId, int payloadLength, bool done) + { + var buffer = _headerEncodingBuffer.AsSpan(); + _outgoingFrame.Length = payloadLength; + + WriteHeaderUnsynchronized(); + _outputWriter.Write(buffer.Slice(0, payloadLength)); + + while (!done) + { + done = _qpackEncoder.Encode(buffer, out payloadLength); + _outgoingFrame.Length = payloadLength; + + WriteHeaderUnsynchronized(); + _outputWriter.Write(buffer.Slice(0, payloadLength)); + } + } + + public void Complete() + { + lock (_writeLock) + { + if (_completed) + { + return; + } + + _completed = true; + _outputWriter.Complete(); + } + } + + public void Abort(ConnectionAbortedException error) + { + lock (_writeLock) + { + if (_aborted) + { + return; + } + + _aborted = true; + _connectionContext.Abort(error); + + Complete(); + } + } + + private static IEnumerable<KeyValuePair<string, string>> EnumerateHeaders(IHeaderDictionary headers) + { + foreach (var header in headers) + { + foreach (var value in header.Value) + { + yield return new KeyValuePair<string, string>(header.Key, value); + } + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs new file mode 100644 index 0000000000..5af5f8df47 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3MessageBody.cs @@ -0,0 +1,126 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO.Pipelines; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal sealed class Http3MessageBody : MessageBody + { + private readonly Http3Stream _context; + private ReadResult _readResult; + + private Http3MessageBody(Http3Stream context) + : base(context) + { + _context = context; + } + protected override void OnReadStarting() + { + // Note ContentLength or MaxRequestBodySize may be null + if (_context.RequestHeaders.ContentLength > _context.MaxRequestBodySize) + { + BadHttpRequestException.Throw(RequestRejectionReason.RequestBodyTooLarge); + } + } + + protected override void OnReadStarted() + { + } + + protected override void OnDataRead(long bytesRead) + { + AddAndCheckConsumedBytes(bytesRead); + } + + public static MessageBody For(Http3Stream context) + { + return new Http3MessageBody(context); + } + + public override void AdvanceTo(SequencePosition consumed) + { + AdvanceTo(consumed, consumed); + } + + public override void AdvanceTo(SequencePosition consumed, SequencePosition examined) + { + OnAdvance(_readResult, consumed, examined); + _context.RequestBodyPipe.Reader.AdvanceTo(consumed, examined); + } + + public override bool TryRead(out ReadResult readResult) + { + TryStart(); + + var hasResult = _context.RequestBodyPipe.Reader.TryRead(out readResult); + + if (hasResult) + { + _readResult = readResult; + + CountBytesRead(readResult.Buffer.Length); + + if (readResult.IsCompleted) + { + TryStop(); + } + } + + return hasResult; + } + + public override async ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default) + { + TryStart(); + + try + { + var readAwaitable = _context.RequestBodyPipe.Reader.ReadAsync(cancellationToken); + + _readResult = await StartTimingReadAsync(readAwaitable, cancellationToken); + } + catch (ConnectionAbortedException ex) + { + throw new TaskCanceledException("The request was aborted", ex); + } + + StopTimingRead(_readResult.Buffer.Length); + + if (_readResult.IsCompleted) + { + TryStop(); + } + + return _readResult; + } + + public override void Complete(Exception exception) + { + _context.RequestBodyPipe.Reader.Complete(); + _context.ReportApplicationError(exception); + } + + public override void CancelPendingRead() + { + _context.RequestBodyPipe.Reader.CancelPendingRead(); + } + + protected override Task OnStopAsync() + { + if (!_context.HasStartedConsumingRequestBody) + { + return Task.CompletedTask; + } + + _context.RequestBodyPipe.Reader.Complete(); + + return Task.CompletedTask; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs new file mode 100644 index 0000000000..bb94b99de1 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3OutputProducer.cs @@ -0,0 +1,406 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeWriterHelpers; +using Microsoft.Extensions.Logging; +using System.Diagnostics; +using Microsoft.AspNetCore.Internal; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal class Http3OutputProducer : IHttpOutputProducer, IHttpOutputAborter + { + private readonly int _streamId; + private readonly Http3FrameWriter _frameWriter; + private readonly TimingPipeFlusher _flusher; + private readonly IKestrelTrace _log; + private readonly MemoryPool<byte> _memoryPool; + private readonly Http3Stream _stream; + private readonly PipeWriter _pipeWriter; + private readonly PipeReader _pipeReader; + private readonly object _dataWriterLock = new object(); + private readonly ValueTask<FlushResult> _dataWriteProcessingTask; + private bool _startedWritingDataFrames; + private bool _completed; + private bool _disposed; + private bool _suffixSent; + private IMemoryOwner<byte> _fakeMemoryOwner; + + public Http3OutputProducer( + int streamId, + Http3FrameWriter frameWriter, + MemoryPool<byte> pool, + Http3Stream stream, + IKestrelTrace log) + { + _streamId = streamId; + _frameWriter = frameWriter; + _memoryPool = pool; + _stream = stream; + _log = log; + + var pipe = CreateDataPipe(pool); + + _pipeWriter = pipe.Writer; + _pipeReader = pipe.Reader; + + _flusher = new TimingPipeFlusher(_pipeWriter, timeoutControl: null, log); + _dataWriteProcessingTask = ProcessDataWrites(); + } + + public void Dispose() + { + lock (_dataWriterLock) + { + if (_disposed) + { + return; + } + + _disposed = true; + + Stop(); + + if (_fakeMemoryOwner != null) + { + _fakeMemoryOwner.Dispose(); + _fakeMemoryOwner = null; + } + } + } + + void IHttpOutputAborter.Abort(ConnectionAbortedException abortReason) + { + _stream.Abort(abortReason, Http3ErrorCode.InternalError); + } + + public void Advance(int bytes) + { + lock (_dataWriterLock) + { + ThrowIfSuffixSent(); + + if (_completed) + { + return; + } + + _startedWritingDataFrames = true; + + _pipeWriter.Advance(bytes); + } + } + + public void CancelPendingFlush() + { + lock (_dataWriterLock) + { + if (_completed) + { + return; + } + + _pipeWriter.CancelPendingFlush(); + } + } + + public ValueTask<FlushResult> FirstWriteAsync(int statusCode, string reasonPhrase, HttpResponseHeaders responseHeaders, bool autoChunk, ReadOnlySpan<byte> data, CancellationToken cancellationToken) + { + lock (_dataWriterLock) + { + WriteResponseHeaders(statusCode, reasonPhrase, responseHeaders, autoChunk, appCompleted: false); + + return WriteDataToPipeAsync(data, cancellationToken); + } + } + + public ValueTask<FlushResult> FirstWriteChunkedAsync(int statusCode, string reasonPhrase, HttpResponseHeaders responseHeaders, bool autoChunk, ReadOnlySpan<byte> data, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask<FlushResult>(Task.FromCanceled<FlushResult>(cancellationToken)); + } + + lock (_dataWriterLock) + { + ThrowIfSuffixSent(); + + if (_completed) + { + return default; + } + + if (_startedWritingDataFrames) + { + // If there's already been response data written to the stream, just wait for that. Any header + // should be in front of the data frames in the connection pipe. Trailers could change things. + return _flusher.FlushAsync(this, cancellationToken); + } + else + { + // Flushing the connection pipe ensures headers already in the pipe are flushed even if no data + // frames have been written. + return _frameWriter.FlushAsync(this, cancellationToken); + } + } + } + + public Memory<byte> GetMemory(int sizeHint = 0) + { + lock (_dataWriterLock) + { + ThrowIfSuffixSent(); + + if (_completed) + { + return GetFakeMemory(sizeHint); + } + + return _pipeWriter.GetMemory(sizeHint); + } + } + + + public Span<byte> GetSpan(int sizeHint = 0) + { + lock (_dataWriterLock) + { + ThrowIfSuffixSent(); + + if (_completed) + { + return GetFakeMemory(sizeHint).Span; + } + + return _pipeWriter.GetSpan(sizeHint); + } + } + + private Memory<byte> GetFakeMemory(int sizeHint) + { + if (_fakeMemoryOwner == null) + { + _fakeMemoryOwner = _memoryPool.Rent(sizeHint); + } + + return _fakeMemoryOwner.Memory; + } + + [StackTraceHidden] + private void ThrowIfSuffixSent() + { + if (_suffixSent) + { + ThrowSuffixSent(); + } + } + + [StackTraceHidden] + private static void ThrowSuffixSent() + { + throw new InvalidOperationException("Writing is not allowed after writer was completed."); + } + + public void Reset() + { + } + + public void Stop() + { + lock (_dataWriterLock) + { + if (_completed) + { + return; + } + + _completed = true; + + _pipeWriter.Complete(new OperationCanceledException()); + + } + } + + public ValueTask<FlushResult> Write100ContinueAsync() + { + throw new NotImplementedException(); + } + + public ValueTask<FlushResult> WriteChunkAsync(ReadOnlySpan<byte> data, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public Task WriteDataAsync(ReadOnlySpan<byte> data, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + lock (_dataWriterLock) + { + ThrowIfSuffixSent(); + + // This length check is important because we don't want to set _startedWritingDataFrames unless a data + // frame will actually be written causing the headers to be flushed. + if (_completed || data.Length == 0) + { + return Task.CompletedTask; + } + + _startedWritingDataFrames = true; + + _pipeWriter.Write(data); + return _flusher.FlushAsync(this, cancellationToken).GetAsTask(); + } + } + + public ValueTask<FlushResult> WriteDataToPipeAsync(ReadOnlySpan<byte> data, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) + { + return new ValueTask<FlushResult>(Task.FromCanceled<FlushResult>(cancellationToken)); + } + + lock (_dataWriterLock) + { + ThrowIfSuffixSent(); + + // This length check is important because we don't want to set _startedWritingDataFrames unless a data + // frame will actually be written causing the headers to be flushed. + if (_completed || data.Length == 0) + { + return default; + } + + _startedWritingDataFrames = true; + + _pipeWriter.Write(data); + return _flusher.FlushAsync(this, cancellationToken); + } + } + + public void WriteResponseHeaders(int statusCode, string reasonPhrase, HttpResponseHeaders responseHeaders, bool autoChunk, bool appCompleted) + { + lock (_dataWriterLock) + { + if (_completed) + { + return; + } + + if (appCompleted && !_startedWritingDataFrames && (_stream.ResponseTrailers == null || _stream.ResponseTrailers.Count == 0)) + { + // TODO figure out something to do here. + } + + _frameWriter.WriteResponseHeaders(_streamId, statusCode, responseHeaders); + } + } + + public ValueTask<FlushResult> WriteStreamSuffixAsync() + { + lock (_dataWriterLock) + { + if (_completed) + { + return _dataWriteProcessingTask; + } + + _completed = true; + _suffixSent = true; + + _pipeWriter.Complete(); + return _dataWriteProcessingTask; + } + } + + private async ValueTask<FlushResult> ProcessDataWrites() + { + FlushResult flushResult = default; + try + { + ReadResult readResult; + + do + { + readResult = await _pipeReader.ReadAsync(); + + if (readResult.IsCompleted && _stream.ResponseTrailers?.Count > 0) + { + // Output is ending and there are trailers to write + // Write any remaining content then write trailers + if (readResult.Buffer.Length > 0) + { + flushResult = await _frameWriter.WriteDataAsync(readResult.Buffer); + } + + _stream.ResponseTrailers.SetReadOnly(); + flushResult = await _frameWriter.WriteResponseTrailers(_streamId, _stream.ResponseTrailers); + } + else if (readResult.IsCompleted) + { + if (readResult.Buffer.Length != 0) + { + ThrowUnexpectedState(); + } + + // Headers have already been written and there is no other content to write + // TODO complete something here. + flushResult = await _frameWriter.FlushAsync(outputAborter: null, cancellationToken: default); + _frameWriter.Complete(); + } + else + { + flushResult = await _frameWriter.WriteDataAsync(readResult.Buffer); + } + + _pipeReader.AdvanceTo(readResult.Buffer.End); + } while (!readResult.IsCompleted); + } + catch (OperationCanceledException) + { + // Writes should not throw for aborted streams/connections. + } + catch (Exception ex) + { + _log.LogCritical(ex, nameof(Http3OutputProducer) + "." + nameof(ProcessDataWrites) + " observed an unexpected exception."); + } + + _pipeReader.Complete(); + + return flushResult; + + static void ThrowUnexpectedState() + { + throw new InvalidOperationException(nameof(Http3OutputProducer) + "." + nameof(ProcessDataWrites) + " observed an unexpected state where the streams output ended with data still remaining in the pipe."); + } + } + + private static Pipe CreateDataPipe(MemoryPool<byte> pool) + => new Pipe(new PipeOptions + ( + pool: pool, + readerScheduler: PipeScheduler.Inline, + writerScheduler: PipeScheduler.ThreadPool, + pauseWriterThreshold: 1, + resumeWriterThreshold: 1, + useSynchronizationContext: false, + minimumSegmentSize: pool.GetMinimumSegmentSize() + )); + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3PeerSettings.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3PeerSettings.cs new file mode 100644 index 0000000000..4a2961d7ec --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3PeerSettings.cs @@ -0,0 +1,12 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal class Http3PeerSettings + { + internal const uint DefaultMaxFrameSize = 16 * 1024; + + public static int MinAllowedMaxFrameSize { get; internal set; } = 16 * 1024; + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3SettingType.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3SettingType.cs new file mode 100644 index 0000000000..325ac0fd91 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3SettingType.cs @@ -0,0 +1,15 @@ +// 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. + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + enum Http3SettingType : long + { + QPackMaxTableCapacity = 0x1, + /// <summary> + /// SETTINGS_MAX_HEADER_LIST_SIZE, default is unlimited. + /// </summary> + MaxHeaderListSize = 0x6, + QPackBlockedStreams = 0x7 + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs new file mode 100644 index 0000000000..e858ddac06 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -0,0 +1,471 @@ +// 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.Diagnostics; +using System.IO.Pipelines; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; +using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + internal abstract class Http3Stream : HttpProtocol, IHttpHeadersHandler, IThreadPoolWorkItem + { + private Http3FrameWriter _frameWriter; + private Http3OutputProducer _http3Output; + private int _isClosed; + private int _gracefulCloseInitiator; + private readonly HttpConnectionContext _context; + private readonly Http3Frame _incomingFrame = new Http3Frame(); + + private readonly Http3Connection _http3Connection; + private bool _receivedHeaders; + public Pipe RequestBodyPipe { get; } + + public Http3Stream(Http3Connection http3Connection, HttpConnectionContext context) : base(context) + { + // First, determine how we know if an Http3stream is unidirectional or bidirectional + var httpLimits = context.ServiceContext.ServerOptions.Limits; + var http3Limits = httpLimits.Http3; + _http3Connection = http3Connection; + _context = context; + + _frameWriter = new Http3FrameWriter( + context.Transport.Output, + context.ConnectionContext, + context.TimeoutControl, + httpLimits.MinResponseDataRate, + context.ConnectionId, + context.MemoryPool, + context.ServiceContext.Log); + + // ResponseHeaders aren't set, kind of ugly that we need to reset. + Reset(); + + _http3Output = new Http3OutputProducer( + 0, // TODO streamid + _frameWriter, + context.MemoryPool, + this, + context.ServiceContext.Log); + RequestBodyPipe = CreateRequestBodyPipe(64 * 1024); // windowSize? + Output = _http3Output; + } + + public QPackDecoder QPackDecoder { get; set; } = new QPackDecoder(10000, 10000); + + public PipeReader Input => _context.Transport.Input; + + public ISystemClock SystemClock => _context.ServiceContext.SystemClock; + public KestrelServerLimits Limits => _context.ServiceContext.ServerOptions.Limits; + + public void Abort(ConnectionAbortedException ex) + { + Abort(ex, Http3ErrorCode.InternalError); + } + + public void Abort(ConnectionAbortedException ex, Http3ErrorCode errorCode) + { + } + + public void OnHeadersComplete(bool endStream) + { + OnHeadersComplete(); + } + + public void HandleReadDataRateTimeout() + { + Log.RequestBodyMinimumDataRateNotSatisfied(ConnectionId, null, Limits.MinRequestBodyDataRate.BytesPerSecond); + Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestBodyTimeout), Http3ErrorCode.RequestRejected); + } + + public void HandleRequestHeadersTimeout() + { + Log.ConnectionBadRequest(ConnectionId, BadHttpRequestException.GetException(RequestRejectionReason.RequestHeadersTimeout)); + Abort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestHeadersTimeout), Http3ErrorCode.RequestRejected); + } + + public void OnInputOrOutputCompleted() + { + TryClose(); + _frameWriter.Abort(new ConnectionAbortedException(CoreStrings.ConnectionAbortedByClient)); + } + + private bool TryClose() + { + if (Interlocked.Exchange(ref _isClosed, 1) == 0) + { + return true; + } + + // TODO make this actually close the Http3Stream by telling msquic to close the stream. + return false; + } + + public async Task ProcessRequestAsync<TContext>(IHttpApplication<TContext> application) + { + try + { + + while (_isClosed == 0) + { + var result = await Input.ReadAsync(); + var readableBuffer = result.Buffer; + var consumed = readableBuffer.Start; + var examined = readableBuffer.End; + + try + { + if (!readableBuffer.IsEmpty) + { + while (Http3FrameReader.TryReadFrame(ref readableBuffer, _incomingFrame, 16 * 1024, out var framePayload)) + { + consumed = examined = framePayload.End; + await ProcessHttp3Stream(application, framePayload); + } + } + + if (result.IsCompleted) + { + return; + } + } + catch (Http3StreamErrorException) + { + // TODO + } + finally + { + Input.AdvanceTo(consumed, examined); + } + } + } + catch (Exception) + { + // TODO + } + finally + { + await RequestBodyPipe.Writer.CompleteAsync(); + } + } + + + private Task ProcessHttp3Stream<TContext>(IHttpApplication<TContext> application, in ReadOnlySequence<byte> payload) + { + switch (_incomingFrame.Type) + { + case Http3FrameType.Data: + return ProcessDataFrameAsync(payload); + case Http3FrameType.Headers: + return ProcessHeadersFrameAsync(application, payload); + // need to be on control stream + case Http3FrameType.DuplicatePush: + case Http3FrameType.PushPromise: + case Http3FrameType.Settings: + case Http3FrameType.GoAway: + case Http3FrameType.CancelPush: + case Http3FrameType.MaxPushId: + throw new Http3ConnectionException("HTTP_FRAME_UNEXPECTED"); + default: + return ProcessUnknownFrameAsync(); + } + } + + private Task ProcessUnknownFrameAsync() + { + // Unknown frames must be explicitly ignored. + return Task.CompletedTask; + } + + private Task ProcessHeadersFrameAsync<TContext>(IHttpApplication<TContext> application, ReadOnlySequence<byte> payload) + { + QPackDecoder.Decode(payload, handler: this); + + // start off a request once qpack has decoded + // Make sure to await this task. + if (_receivedHeaders) + { + // trailers + // TODO figure out if there is anything else to do here. + return Task.CompletedTask; + } + + _receivedHeaders = true; + + Task.Run(() => base.ProcessRequestsAsync(application)); + return Task.CompletedTask; + } + + private Task ProcessDataFrameAsync(in ReadOnlySequence<byte> payload) + { + foreach (var segment in payload) + { + RequestBodyPipe.Writer.Write(segment.Span); + } + + // TODO this can be better. + return RequestBodyPipe.Writer.FlushAsync().AsTask(); + } + + public void StopProcessingNextRequest() + => StopProcessingNextRequest(serverInitiated: true); + + public void StopProcessingNextRequest(bool serverInitiated) + { + var initiator = serverInitiated ? GracefulCloseInitiator.Server : GracefulCloseInitiator.Client; + + if (Interlocked.CompareExchange(ref _gracefulCloseInitiator, initiator, GracefulCloseInitiator.None) == GracefulCloseInitiator.None) + { + Input.CancelPendingRead(); + } + } + + public void Tick(DateTimeOffset now) + { + } + + protected override void OnReset() + { + } + + protected override void ApplicationAbort() + { + } + + protected override string CreateRequestId() + { + // TODO include stream id. + return ConnectionId; + } + + protected override MessageBody CreateMessageBody() + => Http3MessageBody.For(this); + + + protected override bool TryParseRequest(ReadResult result, out bool endConnection) + { + endConnection = !TryValidatePseudoHeaders(); + return true; + } + + private bool TryValidatePseudoHeaders() + { + _httpVersion = Http.HttpVersion.Http3; + + if (!TryValidateMethod()) + { + return false; + } + + if (!TryValidateAuthorityAndHost(out var hostText)) + { + return false; + } + + // CONNECT - :scheme and :path must be excluded + if (Method == Http.HttpMethod.Connect) + { + if (!string.IsNullOrEmpty(RequestHeaders[HeaderNames.Scheme]) || !string.IsNullOrEmpty(RequestHeaders[HeaderNames.Path])) + { + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.Http2ErrorConnectMustNotSendSchemeOrPath), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + + RawTarget = hostText; + + return true; + } + + // :scheme https://tools.ietf.org/html/rfc7540#section-8.1.2.3 + // ":scheme" is not restricted to "http" and "https" schemed URIs. A + // proxy or gateway can translate requests for non - HTTP schemes, + // enabling the use of HTTP to interact with non - HTTP services. + + // - That said, we shouldn't allow arbitrary values or use them to populate Request.Scheme, right? + // - For now we'll restrict it to http/s and require it match the transport. + // - We'll need to find some concrete scenarios to warrant unblocking this. + if (!string.Equals(RequestHeaders[HeaderNames.Scheme], Scheme, StringComparison.OrdinalIgnoreCase)) + { + //ResetAndAbort(new ConnectionAbortedException( + // CoreStrings.FormatHttp2StreamErrorSchemeMismatch(RequestHeaders[HeaderNames.Scheme], Scheme)), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + + // :path (and query) - Required + // Must start with / except may be * for OPTIONS + var path = RequestHeaders[HeaderNames.Path].ToString(); + RawTarget = path; + + // OPTIONS - https://tools.ietf.org/html/rfc7540#section-8.1.2.3 + // This pseudo-header field MUST NOT be empty for "http" or "https" + // URIs; "http" or "https" URIs that do not contain a path component + // MUST include a value of '/'. The exception to this rule is an + // OPTIONS request for an "http" or "https" URI that does not include + // a path component; these MUST include a ":path" pseudo-header field + // with a value of '*'. + if (Method == Http.HttpMethod.Options && path.Length == 1 && path[0] == '*') + { + // * is stored in RawTarget only since HttpRequest expects Path to be empty or start with a /. + Path = string.Empty; + QueryString = string.Empty; + return true; + } + + // Approximate MaxRequestLineSize by totaling the required pseudo header field lengths. + var requestLineLength = _methodText.Length + Scheme.Length + hostText.Length + path.Length; + if (requestLineLength > ServerOptions.Limits.MaxRequestLineSize) + { + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.BadRequest_RequestLineTooLong), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + + var queryIndex = path.IndexOf('?'); + QueryString = queryIndex == -1 ? string.Empty : path.Substring(queryIndex); + + var pathSegment = queryIndex == -1 ? path.AsSpan() : path.AsSpan(0, queryIndex); + + return TryValidatePath(pathSegment); + } + + + private bool TryValidateMethod() + { + // :method + _methodText = RequestHeaders[HeaderNames.Method].ToString(); + Method = HttpUtilities.GetKnownMethod(_methodText); + + if (Method == Http.HttpMethod.None) + { + // TODO + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatHttp2ErrorMethodInvalid(_methodText)), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + + if (Method == Http.HttpMethod.Custom) + { + if (HttpCharacters.IndexOfInvalidTokenChar(_methodText) >= 0) + { + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatHttp2ErrorMethodInvalid(_methodText)), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + } + + return true; + } + + private bool TryValidateAuthorityAndHost(out string hostText) + { + // :authority (optional) + // Prefer this over Host + + var authority = RequestHeaders[HeaderNames.Authority]; + var host = HttpRequestHeaders.HeaderHost; + if (!StringValues.IsNullOrEmpty(authority)) + { + // https://tools.ietf.org/html/rfc7540#section-8.1.2.3 + // Clients that generate HTTP/2 requests directly SHOULD use the ":authority" + // pseudo - header field instead of the Host header field. + // An intermediary that converts an HTTP/2 request to HTTP/1.1 MUST + // create a Host header field if one is not present in a request by + // copying the value of the ":authority" pseudo - header field. + + // We take this one step further, we don't want mismatched :authority + // and Host headers, replace Host if :authority is defined. The application + // will operate on the Host header. + HttpRequestHeaders.HeaderHost = authority; + host = authority; + } + + // https://tools.ietf.org/html/rfc7230#section-5.4 + // A server MUST respond with a 400 (Bad Request) status code to any + // HTTP/1.1 request message that lacks a Host header field and to any + // request message that contains more than one Host header field or a + // Host header field with an invalid field-value. + hostText = host.ToString(); + if (host.Count > 1 || !HttpUtilities.IsHostHeaderValid(hostText)) + { + // RST replaces 400 + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatBadRequest_InvalidHostHeader_Detail(hostText)), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + + return true; + } + + private bool TryValidatePath(ReadOnlySpan<char> pathSegment) + { + // Must start with a leading slash + if (pathSegment.Length == 0 || pathSegment[0] != '/') + { + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatHttp2StreamErrorPathInvalid(RawTarget)), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + + var pathEncoded = pathSegment.Contains('%'); + + // Compare with Http1Connection.OnOriginFormTarget + + // 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; + // then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs" + + try + { + // The decoder operates only on raw bytes + var pathBuffer = new byte[pathSegment.Length].AsSpan(); + for (int i = 0; i < pathSegment.Length; i++) + { + var ch = pathSegment[i]; + // The header parser should already be checking this + Debug.Assert(32 < ch && ch < 127); + pathBuffer[i] = (byte)ch; + } + + Path = PathNormalizer.DecodePath(pathBuffer, pathEncoded, RawTarget, QueryString.Length); + + return true; + } + catch (InvalidOperationException) + { + //ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatHttp2StreamErrorPathInvalid(RawTarget)), Http2ErrorCode.PROTOCOL_ERROR); + return false; + } + } + + private Pipe CreateRequestBodyPipe(uint windowSize) + => new Pipe(new PipeOptions + ( + pool: _context.MemoryPool, + readerScheduler: ServiceContext.Scheduler, + writerScheduler: PipeScheduler.Inline, + // Never pause within the window range. Flow control will prevent more data from being added. + // See the assert in OnDataAsync. + pauseWriterThreshold: windowSize + 1, + resumeWriterThreshold: windowSize + 1, + useSynchronizationContext: false, + minimumSegmentSize: _context.MemoryPool.GetMinimumSegmentSize() + )); + + /// <summary> + /// Used to kick off the request processing loop by derived classes. + /// </summary> + public abstract void Execute(); + + private static class GracefulCloseInitiator + { + public const int None = 0; + public const int Server = 1; + public const int Client = 2; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamErrorException.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamErrorException.cs new file mode 100644 index 0000000000..86952e6a3d --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamErrorException.cs @@ -0,0 +1,18 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + class Http3StreamErrorException : Exception + { + public Http3StreamErrorException(string message, Http3ErrorCode errorCode) + : base($"HTTP/3 stream error ({errorCode}): {message}") + { + ErrorCode = errorCode; + } + + public Http3ErrorCode ErrorCode { get; } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamOfT.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamOfT.cs new file mode 100644 index 0000000000..8d8d6a663f --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3StreamOfT.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Abstractions; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3 +{ + class Http3Stream<TContext> : Http3Stream, IHostContextContainer<TContext> + { + private readonly IHttpApplication<TContext> _application; + + public Http3Stream(IHttpApplication<TContext> application, Http3Connection connection, HttpConnectionContext context) : base(connection, context) + { + _application = application; + } + + public override void Execute() + { + _ = ProcessRequestAsync(_application); + } + + // Pooled Host context + TContext IHostContextContainer<TContext>.HostContext { get; set; } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/DecoderStreamReader.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/DecoderStreamReader.cs new file mode 100644 index 0000000000..6b53b79900 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/DecoderStreamReader.cs @@ -0,0 +1,130 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Buffers; +using System.Net.Http.HPack; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + internal class DecoderStreamReader + { + private enum State + { + Ready, + HeaderAckowledgement, + StreamCancellation, + InsertCountIncrement + } + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 1 | Stream ID(7+) | + //+---+---------------------------+ + private const byte HeaderAcknowledgementMask = 0x80; + private const byte HeaderAcknowledgementRepresentation = 0x80; + private const byte HeaderAcknowledgementPrefixMask = 0x7F; + private const int HeaderAcknowledgementPrefix = 7; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 1 | Stream ID(6+) | + //+---+---+-----------------------+ + private const byte StreamCancellationMask = 0xC0; + private const byte StreamCancellationRepresentation = 0x40; + private const byte StreamCancellationPrefixMask = 0x3F; + private const int StreamCancellationPrefix = 6; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 0 | Increment(6+) | + //+---+---+-----------------------+ + private const byte InsertCountIncrementMask = 0xC0; + private const byte InsertCountIncrementRepresentation = 0x00; + private const byte InsertCountIncrementPrefixMask = 0x3F; + private const int InsertCountIncrementPrefix = 6; + + private IntegerDecoder _integerDecoder = new IntegerDecoder(); + private State _state; + + public DecoderStreamReader() + { + } + + public void Read(ReadOnlySequence<byte> data) + { + foreach (var segment in data) + { + var span = segment.Span; + for (var i = 0; i < span.Length; i++) + { + OnByte(span[i]); + } + } + } + + private void OnByte(byte b) + { + int intResult; + int prefixInt; + switch (_state) + { + case State.Ready: + if ((b & HeaderAcknowledgementMask) == HeaderAcknowledgementRepresentation) + { + prefixInt = HeaderAcknowledgementPrefixMask & b; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, HeaderAcknowledgementPrefix, out intResult)) + { + OnHeaderAcknowledgement(intResult); + } + else + { + _state = State.HeaderAckowledgement; + } + } + else if ((b & StreamCancellationMask) == StreamCancellationRepresentation) + { + prefixInt = StreamCancellationPrefixMask & b; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, StreamCancellationPrefix, out intResult)) + { + OnStreamCancellation(intResult); + } + else + { + _state = State.StreamCancellation; + } + } + else if ((b & InsertCountIncrementMask) == InsertCountIncrementRepresentation) + { + prefixInt = InsertCountIncrementPrefixMask & b; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, InsertCountIncrementPrefix, out intResult)) + { + OnInsertCountIncrement(intResult); + } + else + { + _state = State.InsertCountIncrement; + } + } + break; + } + } + + private void OnInsertCountIncrement(int intResult) + { + // increment some count. + _state = State.Ready; + } + + private void OnStreamCancellation(int streamId) + { + // Remove stream? + _state = State.Ready; + } + + private void OnHeaderAcknowledgement(int intResult) + { + // Acknowledge header somehow + _state = State.Ready; + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/DynamicTable.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/DynamicTable.cs new file mode 100644 index 0000000000..bd48915bea --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/DynamicTable.cs @@ -0,0 +1,46 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + // The size of the dynamic table is the sum of the size of its entries. + // The size of an entry is the sum of its name's length in bytes (as + // defined in Section 4.1.2), its value's length in bytes, and 32. + + internal class DynamicTable + { + + // The encoder sends a Set Dynamic Table Capacity + // instruction(Section 4.3.1) with a non-zero capacity to begin using + // the dynamic table. + public DynamicTable(int maxSize) + { + } + + public HeaderField this[int index] + { + get + { + return new HeaderField(); + } + } + + // TODO + public void Insert(Span<byte> name, Span<byte> value) + { + } + + // TODO + public void Resize(int maxSize) + { + } + + // TODO + internal void Duplicate(int index) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/EncoderStreamReader.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/EncoderStreamReader.cs new file mode 100644 index 0000000000..e2d769507f --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/EncoderStreamReader.cs @@ -0,0 +1,332 @@ +// 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.Net.Http.HPack; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + internal class EncoderStreamReader + { + private enum State + { + Ready, + DynamicTableCapcity, + NameIndex, + NameLength, + Name, + ValueLength, + ValueLengthContinue, + Value, + Duplicate + } + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 0 | 1 | Capacity(5+) | + //+---+---+---+-------------------+ + private const byte DynamicTableCapacityMask = 0xE0; + private const byte DynamicTableCapacityRepresentation = 0x20; + private const byte DynamicTableCapacityPrefixMask = 0x1F; + private const int DynamicTableCapacityPrefix = 5; + + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 1 | S | Name Index(6+) | + //+---+---+-----------------------+ + //| H | Value Length(7+) | + //+---+---------------------------+ + //| Value String(Length bytes) | + //+-------------------------------+ + private const byte InsertWithNameReferenceMask = 0x80; + private const byte InsertWithNameReferenceRepresentation = 0x80; + private const byte InsertWithNameReferencePrefixMask = 0x3F; + private const byte InsertWithNameReferenceStaticMask = 0x40; + private const int InsertWithNameReferencePrefix = 6; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 1 | H | Name Length(5+) | + //+---+---+---+-------------------+ + //| Name String(Length bytes) | + //+---+---------------------------+ + //| H | Value Length(7+) | + //+---+---------------------------+ + //| Value String(Length bytes) | + //+-------------------------------+ + private const byte InsertWithoutNameReferenceMask = 0xC0; + private const byte InsertWithoutNameReferenceRepresentation = 0x40; + private const byte InsertWithoutNameReferencePrefixMask = 0x1F; + private const byte InsertWithoutNameReferenceHuffmanMask = 0x20; + private const int InsertWithoutNameReferencePrefix = 5; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 0 | 0 | Index(5+) | + //+---+---+---+-------------------+ + private const byte DuplicateMask = 0xE0; + private const byte DuplicateRepresentation = 0x00; + private const byte DuplicatePrefixMask = 0x1F; + private const int DuplicatePrefix = 5; + + private const int StringLengthPrefix = 7; + private const byte HuffmanMask = 0x80; + + private bool _s; + private byte[] _stringOctets; + private byte[] _headerNameOctets; + private byte[] _headerValueOctets; + private byte[] _headerName; + private int _headerNameLength; + private int _headerValueLength; + private int _stringLength; + private int _stringIndex; + private DynamicTable _dynamicTable = new DynamicTable(1000); // TODO figure out architecture. + + private readonly IntegerDecoder _integerDecoder = new IntegerDecoder(); + private State _state = State.Ready; + private bool _huffman; + + public EncoderStreamReader(int maxRequestHeaderFieldSize) + { + // TODO how to propagate dynamic table around. + + _stringOctets = new byte[maxRequestHeaderFieldSize]; + _headerNameOctets = new byte[maxRequestHeaderFieldSize]; + _headerValueOctets = new byte[maxRequestHeaderFieldSize]; + } + + public void Read(ReadOnlySequence<byte> data) + { + foreach (var segment in data) + { + var span = segment.Span; + for (var i = 0; i < span.Length; i++) + { + OnByte(span[i]); + } + } + } + + private void OnByte(byte b) + { + int intResult; + int prefixInt; + switch (_state) + { + case State.Ready: + if ((b & DynamicTableCapacityMask) == DynamicTableCapacityRepresentation) + { + prefixInt = DynamicTableCapacityPrefixMask & b; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, DynamicTableCapacityPrefix, out intResult)) + { + OnDynamicTableCapacity(intResult); + } + else + { + _state = State.DynamicTableCapcity; + } + } + else if ((b & InsertWithNameReferenceMask) == InsertWithNameReferenceRepresentation) + { + prefixInt = InsertWithNameReferencePrefixMask & b; + _s = (InsertWithNameReferenceStaticMask & b) == InsertWithNameReferenceStaticMask; + + if (_integerDecoder.BeginTryDecode((byte)prefixInt, InsertWithNameReferencePrefix, out intResult)) + { + OnNameIndex(intResult); + } + else + { + _state = State.NameIndex; + } + } + else if ((b & InsertWithoutNameReferenceMask) == InsertWithoutNameReferenceRepresentation) + { + prefixInt = InsertWithoutNameReferencePrefixMask & b; + _huffman = (InsertWithoutNameReferenceHuffmanMask & b) == InsertWithoutNameReferenceHuffmanMask; + + if (_integerDecoder.BeginTryDecode((byte)prefixInt, InsertWithoutNameReferencePrefix, out intResult)) + { + OnStringLength(intResult, State.Name); + } + else + { + _state = State.NameIndex; + } + } + else if ((b & DuplicateMask) == DuplicateRepresentation) + { + prefixInt = DuplicatePrefixMask & b; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, DuplicatePrefix, out intResult)) + { + OnDuplicate(intResult); + } + else + { + _state = State.Duplicate; + } + } + break; + case State.DynamicTableCapcity: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnDynamicTableCapacity(intResult); + } + break; + case State.NameIndex: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnNameIndex(intResult); + } + break; + case State.NameLength: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnStringLength(intResult, nextState: State.Name); + } + break; + case State.Name: + _stringOctets[_stringIndex++] = b; + + if (_stringIndex == _stringLength) + { + OnString(nextState: State.ValueLength); + } + + break; + case State.ValueLength: + _huffman = (b & HuffmanMask) != 0; + + // TODO confirm this. + if (_integerDecoder.BeginTryDecode((byte)(b & ~HuffmanMask), StringLengthPrefix, out intResult)) + { + OnStringLength(intResult, nextState: State.Value); + if (intResult == 0) + { + ProcessValue(); + } + } + else + { + _state = State.ValueLengthContinue; + } + break; + case State.ValueLengthContinue: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnStringLength(intResult, nextState: State.Value); + if (intResult == 0) + { + ProcessValue(); + } + } + break; + case State.Value: + _stringOctets[_stringIndex++] = b; + if (_stringIndex == _stringLength) + { + ProcessValue(); + } + break; + case State.Duplicate: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnDuplicate(intResult); + } + break; + } + } + + + private void OnStringLength(int length, State nextState) + { + if (length > _stringOctets.Length) + { + throw new QPackDecodingException(/*CoreStrings.FormatQPackStringLengthTooLarge(length, _stringOctets.Length)*/); + } + + _stringLength = length; + _stringIndex = 0; + _state = nextState; + } + + private void ProcessValue() + { + OnString(nextState: State.Ready); + var headerNameSpan = new Span<byte>(_headerName, 0, _headerNameLength); + var headerValueSpan = new Span<byte>(_headerValueOctets, 0, _headerValueLength); + _dynamicTable.Insert(headerNameSpan, headerValueSpan); + } + + private void OnString(State nextState) + { + int Decode(byte[] dst) + { + if (_huffman) + { + return Huffman.Decode(new ReadOnlySpan<byte>(_stringOctets, 0, _stringLength), ref dst); + } + else + { + Buffer.BlockCopy(_stringOctets, 0, dst, 0, _stringLength); + return _stringLength; + } + } + + try + { + if (_state == State.Name) + { + _headerName = _headerNameOctets; + _headerNameLength = Decode(_headerNameOctets); + } + else + { + _headerValueLength = Decode(_headerValueOctets); + } + } + catch (HuffmanDecodingException ex) + { + throw new QPackDecodingException(""/*CoreStrings.QPackHuffmanError*/, ex); + } + + _state = nextState; + } + + private void OnNameIndex(int index) + { + var header = GetHeader(index); + _headerName = header.Name; + _headerNameLength = header.Name.Length; + _state = State.ValueLength; + } + + private void OnDynamicTableCapacity(int dynamicTableSize) + { + // Call Decoder to update the table size. + _dynamicTable.Resize(dynamicTableSize); + _state = State.Ready; + } + + private void OnDuplicate(int index) + { + _dynamicTable.Duplicate(index); + _state = State.Ready; + } + + private HeaderField GetHeader(int index) + { + try + { + return _s ? StaticTable.Instance[index] : _dynamicTable[index]; + } + catch (IndexOutOfRangeException ex) + { + throw new QPackDecodingException( "" /*CoreStrings.FormatQPackErrorIndexOutOfRange(index)*/, ex); + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HeaderField.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/HeaderField.cs similarity index 82% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HeaderField.cs rename to src/Servers/Kestrel/Core/src/Internal/Http3/QPack/HeaderField.cs index d6a07e7b35..d929187de5 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HeaderField.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/HeaderField.cs @@ -3,13 +3,10 @@ using System; -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack { internal readonly struct HeaderField { - // http://httpwg.org/specs/rfc7541.html#rfc.section.4.1 - public const int RfcOverhead = 32; - public HeaderField(Span<byte> name, Span<byte> value) { Name = new byte[name.Length]; @@ -25,6 +22,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack public int Length => GetLength(Name.Length, Value.Length); - public static int GetLength(int nameLength, int valueLength) => nameLength + valueLength + 32; + public static int GetLength(int nameLength, int valueLength) => nameLength + valueLength; } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackDecoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackDecoder.cs new file mode 100644 index 0000000000..538a9ff2fc --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackDecoder.cs @@ -0,0 +1,513 @@ +// 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.Net.Http.HPack; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + internal class QPackDecoder + { + private enum State + { + Ready, + RequiredInsertCount, + RequiredInsertCountDone, + Base, + CompressedHeaders, + HeaderFieldIndex, + HeaderNameIndex, + HeaderNameLength, + HeaderNameLengthContinue, + HeaderName, + HeaderValueLength, + HeaderValueLengthContinue, + HeaderValue, + DynamicTableSizeUpdate, + PostBaseIndex, + LiteralHeaderFieldWithNameReference, + HeaderNameIndexPostBase + } + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| Required Insert Count(8+) | + //+---+---------------------------+ + //| S | Delta Base(7+) | + //+---+---------------------------+ + //| Compressed Headers ... + private const int RequiredInsertCountPrefix = 8; + private const int BaseMask = 0x80; + private const int BasePrefix = 7; + //+-------------------------------+ + + //https://tools.ietf.org/html/draft-ietf-quic-qpack-09#section-4.5.2 + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 1 | S | Index(6+) | + //+---+---+-----------------------+ + private const byte IndexedHeaderFieldMask = 0x80; + private const byte IndexedHeaderFieldRepresentation = 0x80; + private const byte IndexedHeaderStaticMask = 0x40; + private const byte IndexedHeaderStaticRepresentation = 0x40; + private const byte IndexedHeaderFieldPrefixMask = 0x3F; + private const int IndexedHeaderFieldPrefix = 6; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 0 | 0 | 1 | Index(4+) | + //+---+---+---+---+---------------+ + private const byte PostBaseIndexMask = 0xF0; + private const byte PostBaseIndexRepresentation = 0x10; + private const int PostBaseIndexPrefix = 4; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 1 | N | S |Name Index(4+)| + //+---+---+---+---+---------------+ + //| H | Value Length(7+) | + //+---+---------------------------+ + //| Value String(Length bytes) | + //+-------------------------------+ + private const byte LiteralHeaderFieldMask = 0xC0; + private const byte LiteralHeaderFieldRepresentation = 0x40; + private const byte LiteralHeaderFieldNMask = 0x20; + private const byte LiteralHeaderFieldStaticMask = 0x10; + private const byte LiteralHeaderFieldPrefixMask = 0x0F; + private const int LiteralHeaderFieldPrefix = 4; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 0 | 0 | 0 | N |NameIdx(3+)| + //+---+---+---+---+---+-----------+ + //| H | Value Length(7+) | + //+---+---------------------------+ + //| Value String(Length bytes) | + //+-------------------------------+ + private const byte LiteralHeaderFieldPostBaseMask = 0xF0; + private const byte LiteralHeaderFieldPostBaseRepresentation = 0x00; + private const byte LiteralHeaderFieldPostBaseNMask = 0x08; + private const byte LiteralHeaderFieldPostBasePrefixMask = 0x07; + private const int LiteralHeaderFieldPostBasePrefix = 3; + + //0 1 2 3 4 5 6 7 + //+---+---+---+---+---+---+---+---+ + //| 0 | 0 | 1 | N | H |NameLen(3+)| + //+---+---+---+---+---+-----------+ + //| Name String(Length bytes) | + //+---+---------------------------+ + //| H | Value Length(7+) | + //+---+---------------------------+ + //| Value String(Length bytes) | + //+-------------------------------+ + private const byte LiteralHeaderFieldWithoutNameReferenceMask = 0xE0; + private const byte LiteralHeaderFieldWithoutNameReferenceRepresentation = 0x20; + private const byte LiteralHeaderFieldWithoutNameReferenceNMask = 0x10; + private const byte LiteralHeaderFieldWithoutNameReferenceHuffmanMask = 0x08; + private const byte LiteralHeaderFieldWithoutNameReferencePrefixMask = 0x07; + private const int LiteralHeaderFieldWithoutNameReferencePrefix = 3; + + private const int StringLengthPrefix = 7; + private const byte HuffmanMask = 0x80; + + private State _state = State.Ready; + // TODO break out dynamic table entirely. + private long _maxDynamicTableSize; + private DynamicTable _dynamicTable; + + // TODO idk what these are for. + private byte[] _stringOctets; + private byte[] _headerNameOctets; + private byte[] _headerValueOctets; + private int _requiredInsertCount; + //private int _insertCount; + private int _base; + + // s is used for whatever s is in each field. This has multiple definition + private bool _s; + private bool _n; + private bool _huffman; + private bool _index; + + private byte[] _headerName; + private int _headerNameLength; + private int _headerValueLength; + private int _stringLength; + private int _stringIndex; + private readonly IntegerDecoder _integerDecoder = new IntegerDecoder(); + + // Decoders are on the http3stream now, each time we see a header block + public QPackDecoder(int maxDynamicTableSize, int maxRequestHeaderFieldSize) + : this(maxDynamicTableSize, maxRequestHeaderFieldSize, new DynamicTable(maxDynamicTableSize)) { } + + + // For testing. + internal QPackDecoder(int maxDynamicTableSize, int maxRequestHeaderFieldSize, DynamicTable dynamicTable) + { + _maxDynamicTableSize = maxDynamicTableSize; + _dynamicTable = dynamicTable; + + _stringOctets = new byte[maxRequestHeaderFieldSize]; + _headerNameOctets = new byte[maxRequestHeaderFieldSize]; + _headerValueOctets = new byte[maxRequestHeaderFieldSize]; + } + + // sequence will probably be a header block instead. + public void Decode(in ReadOnlySequence<byte> headerBlock, IHttpHeadersHandler handler) + { + // TODO I need to get the RequiredInsertCount and DeltaBase + // These are always present in the header block + // TODO need to figure out if I have read an entire header block. + + // (I think this can be done based on length outside of this) + foreach (var segment in headerBlock) + { + var span = segment.Span; + for (var i = 0; i < span.Length; i++) + { + OnByte(span[i], handler); + } + } + } + + private void OnByte(byte b, IHttpHeadersHandler handler) + { + int intResult; + int prefixInt; + switch (_state) + { + case State.Ready: + if (_integerDecoder.BeginTryDecode(b, RequiredInsertCountPrefix, out intResult)) + { + OnRequiredInsertCount(intResult); + } + else + { + _state = State.RequiredInsertCount; + } + break; + case State.RequiredInsertCount: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnRequiredInsertCount(intResult); + } + break; + case State.RequiredInsertCountDone: + prefixInt = ~BaseMask & b; + + _s = (b & BaseMask) == BaseMask; + + if (_integerDecoder.BeginTryDecode(b, BasePrefix, out intResult)) + { + OnBase(intResult); + } + else + { + _state = State.Base; + } + break; + case State.Base: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnBase(intResult); + } + break; + case State.CompressedHeaders: + if ((b & IndexedHeaderFieldMask) == IndexedHeaderFieldRepresentation) + { + prefixInt = IndexedHeaderFieldPrefixMask & b; + _s = (b & IndexedHeaderStaticMask) == IndexedHeaderStaticRepresentation; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, IndexedHeaderFieldPrefix, out intResult)) + { + OnIndexedHeaderField(intResult, handler); + } + else + { + _state = State.HeaderFieldIndex; + } + } + else if ((b & PostBaseIndexMask) == PostBaseIndexRepresentation) + { + prefixInt = ~PostBaseIndexMask & b; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, PostBaseIndexPrefix, out intResult)) + { + OnPostBaseIndex(intResult, handler); + } + else + { + _state = State.PostBaseIndex; + } + } + else if ((b & LiteralHeaderFieldMask) == LiteralHeaderFieldRepresentation) + { + _index = true; + // Represents whether an intermediary is permitted to add this header to the dynamic header table on + // subsequent hops. + // if n is set, the encoded header must always be encoded with a literal representation + + _n = (LiteralHeaderFieldNMask & b) == LiteralHeaderFieldNMask; + _s = (LiteralHeaderFieldStaticMask & b) == LiteralHeaderFieldStaticMask; + prefixInt = b & LiteralHeaderFieldPrefixMask; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, LiteralHeaderFieldPrefix, out intResult)) + { + OnIndexedHeaderName(intResult); + } + else + { + _state = State.HeaderNameIndex; + } + } + else if ((b & LiteralHeaderFieldPostBaseMask) == LiteralHeaderFieldPostBaseRepresentation) + { + _index = true; + _n = (LiteralHeaderFieldPostBaseNMask & b) == LiteralHeaderFieldPostBaseNMask; + prefixInt = b & LiteralHeaderFieldPostBasePrefixMask; + if (_integerDecoder.BeginTryDecode((byte)prefixInt, LiteralHeaderFieldPostBasePrefix, out intResult)) + { + OnIndexedHeaderNamePostBase(intResult); + } + else + { + _state = State.HeaderNameIndexPostBase; + } + } + else if ((b & LiteralHeaderFieldWithoutNameReferenceMask) == LiteralHeaderFieldWithoutNameReferenceRepresentation) + { + _index = false; + _n = (LiteralHeaderFieldWithoutNameReferenceNMask & b) == LiteralHeaderFieldWithoutNameReferenceNMask; + _huffman = (b & LiteralHeaderFieldWithoutNameReferenceHuffmanMask) != 0; + prefixInt = b & LiteralHeaderFieldWithoutNameReferencePrefixMask; + + if (_integerDecoder.BeginTryDecode((byte)prefixInt, LiteralHeaderFieldWithoutNameReferencePrefix, out intResult)) + { + OnStringLength(intResult, State.HeaderName); + } + else + { + _state = State.HeaderNameLength; + } + } + break; + case State.HeaderNameLength: + // huffman has already been processed. + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnStringLength(intResult, nextState: State.HeaderName); + } + break; + case State.HeaderName: + _stringOctets[_stringIndex++] = b; + + if (_stringIndex == _stringLength) + { + OnString(nextState: State.HeaderValueLength); + } + + break; + case State.HeaderNameIndex: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnIndexedHeaderName(intResult); + } + break; + case State.HeaderNameIndexPostBase: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnIndexedHeaderNamePostBase(intResult); + } + break; + case State.HeaderValueLength: + _huffman = (b & HuffmanMask) != 0; + + // TODO confirm this. + if (_integerDecoder.BeginTryDecode((byte)(b & ~HuffmanMask), StringLengthPrefix, out intResult)) + { + OnStringLength(intResult, nextState: State.HeaderValue); + if (intResult == 0) + { + ProcessHeaderValue(handler); + } + } + else + { + _state = State.HeaderValueLengthContinue; + } + break; + case State.HeaderValueLengthContinue: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnStringLength(intResult, nextState: State.HeaderValue); + if (intResult == 0) + { + ProcessHeaderValue(handler); + } + } + break; + case State.HeaderValue: + _stringOctets[_stringIndex++] = b; + if (_stringIndex == _stringLength) + { + ProcessHeaderValue(handler); + } + break; + case State.HeaderFieldIndex: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnIndexedHeaderField(intResult, handler); + } + break; + case State.PostBaseIndex: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnPostBaseIndex(intResult, handler); + } + break; + case State.LiteralHeaderFieldWithNameReference: + break; + } + } + + private void OnStringLength(int length, State nextState) + { + if (length > _stringOctets.Length) + { + throw new QPackDecodingException("TODO sync with corefx" /*CoreStrings.FormatQPackStringLengthTooLarge(length, _stringOctets.Length)*/); + } + + _stringLength = length; + _stringIndex = 0; + _state = nextState; + } + + private void ProcessHeaderValue(IHttpHeadersHandler handler) + { + OnString(nextState: State.CompressedHeaders); + + var headerNameSpan = new Span<byte>(_headerName, 0, _headerNameLength); + var headerValueSpan = new Span<byte>(_headerValueOctets, 0, _headerValueLength); + + handler.OnHeader(headerNameSpan, headerValueSpan); + + if (_index) + { + _dynamicTable.Insert(headerNameSpan, headerValueSpan); + } + } + + private void OnString(State nextState) + { + int Decode(byte[] dst) + { + if (_huffman) + { + return Huffman.Decode(new ReadOnlySpan<byte>(_stringOctets, 0, _stringLength), ref dst); + } + else + { + Buffer.BlockCopy(_stringOctets, 0, dst, 0, _stringLength); + return _stringLength; + } + } + + try + { + if (_state == State.HeaderName) + { + _headerName = _headerNameOctets; + _headerNameLength = Decode(_headerNameOctets); + } + else + { + _headerValueLength = Decode(_headerValueOctets); + } + } + catch (HuffmanDecodingException ex) + { + throw new QPackDecodingException("TODO sync with corefx" /*CoreStrings.QPackHuffmanError, */, ex); + } + + _state = nextState; + } + + + private void OnIndexedHeaderName(int index) + { + var header = GetHeader(index); + _headerName = header.Name; + _headerNameLength = header.Name.Length; + _state = State.HeaderValueLength; + } + + private void OnIndexedHeaderNamePostBase(int index) + { + // TODO update with postbase index + var header = GetHeader(index); + _headerName = header.Name; + _headerNameLength = header.Name.Length; + _state = State.HeaderValueLength; + } + + private void OnPostBaseIndex(int intResult, IHttpHeadersHandler handler) + { + // TODO + _state = State.CompressedHeaders; + } + + private void OnBase(int deltaBase) + { + _state = State.CompressedHeaders; + if (_s) + { + _base = _requiredInsertCount - deltaBase - 1; + } + else + { + _base = _requiredInsertCount + deltaBase; + } + } + + // TODO + private void OnRequiredInsertCount(int requiredInsertCount) + { + _requiredInsertCount = requiredInsertCount; + _state = State.RequiredInsertCountDone; + // This is just going to noop for now. I don't get this algorithm at all. + // var encoderInsertCount = 0; + // var maxEntries = _maxDynamicTableSize / HeaderField.RfcOverhead; + + // if (requiredInsertCount != 0) + // { + // encoderInsertCount = (requiredInsertCount % ( 2 * maxEntries)) + 1; + // } + + // // Dude I don't get this algorithm... + // var fullRange = 2 * maxEntries; + // if (encoderInsertCount == 0) + // { + + // } + } + + private void OnIndexedHeaderField(int index, IHttpHeadersHandler handler) + { + // Indexes start at 0 in QPack + var header = GetHeader(index); + handler.OnHeader(new Span<byte>(header.Name), new Span<byte>(header.Value)); + _state = State.CompressedHeaders; + } + + private HeaderField GetHeader(int index) + { + try + { + return _s ? StaticTable.Instance[index] : _dynamicTable[index]; + } + catch (IndexOutOfRangeException ex) + { + throw new QPackDecodingException("TODO sync with corefx" /*CoreStrings.FormatQPackErrorIndexOutOfRange(index), */, ex); + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackDecodingException.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackDecodingException.cs new file mode 100644 index 0000000000..fb648d3045 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackDecodingException.cs @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.Serialization; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + [Serializable] + internal class QPackDecodingException : Exception + { + public QPackDecodingException() + { + } + + public QPackDecodingException(string message) : base(message) + { + } + + public QPackDecodingException(string message, Exception innerException) : base(message, innerException) + { + } + + protected QPackDecodingException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackEncoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackEncoder.cs new file mode 100644 index 0000000000..44a5e20ea5 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackEncoder.cs @@ -0,0 +1,504 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.Http; +using System.Net.Http.HPack; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + internal class QPackEncoder + { + private IEnumerator<KeyValuePair<string, string>> _enumerator; + + // TODO these all need to be updated! + + /* + * 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | 1 | S | Index (6+) | + +---+---+-----------------------+ + */ + public static bool EncodeIndexedHeaderField(int index, Span<byte> destination, out int bytesWritten) + { + if (destination.IsEmpty) + { + bytesWritten = 0; + return false; + } + + EncodeHeaderBlockPrefix(destination, out bytesWritten); + destination = destination.Slice(bytesWritten); + + return IntegerEncoder.Encode(index, 6, destination, out bytesWritten); + } + + public static bool EncodeIndexHeaderFieldWithPostBaseIndex(int index, Span<byte> destination, out int bytesWritten) + { + bytesWritten = 0; + return false; + } + + /// <summary>Encodes a "Literal Header Field without Indexing".</summary> + public static bool EncodeLiteralHeaderFieldWithNameReference(int index, string value, Span<byte> destination, out int bytesWritten) + { + if (destination.IsEmpty) + { + bytesWritten = 0; + return false; + } + + EncodeHeaderBlockPrefix(destination, out bytesWritten); + destination = destination.Slice(bytesWritten); + + return IntegerEncoder.Encode(index, 6, destination, out bytesWritten); + } + + /* + * 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | 0 | 1 | N | S |Name Index (4+)| + +---+---+---+---+---------------+ + | H | Value Length (7+) | + +---+---------------------------+ + | Value String (Length bytes) | + +-------------------------------+ + */ + public static bool EncodeLiteralHeaderFieldWithPostBaseNameReference(int index, Span<byte> destination, out int bytesWritten) + { + bytesWritten = 0; + return false; + } + + public static bool EncodeLiteralHeaderFieldWithoutNameReference(int index, Span<byte> destination, out int bytesWritten) + { + bytesWritten = 0; + return false; + } + + /* + * 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | Required Insert Count (8+) | + +---+---------------------------+ + | S | Delta Base (7+) | + +---+---------------------------+ + | Compressed Headers ... + +-------------------------------+ + * + */ + private static bool EncodeHeaderBlockPrefix(Span<byte> destination, out int bytesWritten) + { + int length; + bytesWritten = 0; + // Required insert count as first int + if (!IntegerEncoder.Encode(0, 8, destination, out length)) + { + return false; + } + + bytesWritten += length; + destination = destination.Slice(length); + + // Delta base + if (destination.IsEmpty) + { + return false; + } + + destination[0] = 0x00; + if (!IntegerEncoder.Encode(0, 7, destination, out length)) + { + return false; + } + + bytesWritten += length; + + return true; + } + + private static bool EncodeLiteralHeaderName(string value, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-5.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | H | String Length (7+) | + // +---+---------------------------+ + // | String Data (Length octets) | + // +-------------------------------+ + + if (!destination.IsEmpty) + { + destination[0] = 0; // TODO: Use Huffman encoding + if (IntegerEncoder.Encode(value.Length, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + destination = destination.Slice(integerLength); + if (value.Length <= destination.Length) + { + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + destination[i] = (byte)((uint)(c - 'A') <= ('Z' - 'A') ? c | 0x20 : c); + } + + bytesWritten = integerLength + value.Length; + return true; + } + } + } + + bytesWritten = 0; + return false; + } + + private static bool EncodeStringLiteralValue(string value, Span<byte> destination, out int bytesWritten) + { + if (value.Length <= destination.Length) + { + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + if ((c & 0xFF80) != 0) + { + throw new HttpRequestException(""); + } + + destination[i] = (byte)c; + } + + bytesWritten = value.Length; + return true; + } + + bytesWritten = 0; + return false; + } + + public static bool EncodeStringLiteral(string value, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-5.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | H | String Length (7+) | + // +---+---------------------------+ + // | String Data (Length octets) | + // +-------------------------------+ + + if (!destination.IsEmpty) + { + destination[0] = 0; // TODO: Use Huffman encoding + if (IntegerEncoder.Encode(value.Length, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + if (EncodeStringLiteralValue(value, destination.Slice(integerLength), out int valueLength)) + { + bytesWritten = integerLength + valueLength; + return true; + } + } + } + + bytesWritten = 0; + return false; + } + + public static bool EncodeStringLiterals(string[] values, string separator, Span<byte> destination, out int bytesWritten) + { + bytesWritten = 0; + + if (values.Length == 0) + { + return EncodeStringLiteral("", destination, out bytesWritten); + } + else if (values.Length == 1) + { + return EncodeStringLiteral(values[0], destination, out bytesWritten); + } + + if (!destination.IsEmpty) + { + int valueLength = 0; + + // Calculate length of all parts and separators. + foreach (string part in values) + { + valueLength = checked((int)(valueLength + part.Length)); + } + + valueLength = checked((int)(valueLength + (values.Length - 1) * separator.Length)); + + if (IntegerEncoder.Encode(valueLength, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + int encodedLength = 0; + for (int j = 0; j < values.Length; j++) + { + if (j != 0 && !EncodeStringLiteralValue(separator, destination.Slice(integerLength), out encodedLength)) + { + return false; + } + + integerLength += encodedLength; + + if (!EncodeStringLiteralValue(values[j], destination.Slice(integerLength), out encodedLength)) + { + return false; + } + + integerLength += encodedLength; + } + + bytesWritten = integerLength; + return true; + } + } + + return false; + } + + /// <summary> + /// Encodes a "Literal Header Field without Indexing" to a new array, but only the index portion; + /// a subsequent call to <see cref="EncodeStringLiteral"/> must be used to encode the associated value. + /// </summary> + public static byte[] EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(int index) + { + Span<byte> span = stackalloc byte[256]; + bool success = EncodeLiteralHeaderFieldWithPostBaseNameReference(index, span, out int length); + Debug.Assert(success, $"Stack-allocated space was too small for index '{index}'."); + return span.Slice(0, length).ToArray(); + } + + /// <summary> + /// Encodes a "Literal Header Field without Indexing - New Name" to a new array, but only the name portion; + /// a subsequent call to <see cref="EncodeStringLiteral"/> must be used to encode the associated value. + /// </summary> + public static byte[] EncodeLiteralHeaderFieldWithoutIndexingNewNameToAllocatedArray(string name) + { + Span<byte> span = stackalloc byte[256]; + bool success = EncodeLiteralHeaderFieldWithoutIndexingNewName(name, span, out int length); + Debug.Assert(success, $"Stack-allocated space was too small for \"{name}\"."); + return span.Slice(0, length).ToArray(); + } + + private static bool EncodeLiteralHeaderFieldWithoutIndexingNewName(string name, Span<byte> span, out int length) + { + throw new NotImplementedException(); + } + + /// <summary>Encodes a "Literal Header Field without Indexing" to a new array.</summary> + public static byte[] EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(int index, string value) + { + Span<byte> span = +#if DEBUG + stackalloc byte[4]; // to validate growth algorithm +#else + stackalloc byte[512]; +#endif + while (true) + { + if (EncodeLiteralHeaderFieldWithNameReference(index, value, span, out int length)) + { + return span.Slice(0, length).ToArray(); + } + + // This is a rare path, only used once per HTTP/2 connection and only + // for very long host names. Just allocate rather than complicate + // the code with ArrayPool usage. In practice we should never hit this, + // as hostnames should be <= 255 characters. + span = new byte[span.Length * 2]; + } + } + + // TODO these are fairly hard coded for the first two bytes to be zero. + public bool BeginEncode(IEnumerable<KeyValuePair<string, string>> headers, Span<byte> buffer, out int length) + { + _enumerator = headers.GetEnumerator(); + _enumerator.MoveNext(); + buffer[0] = 0; + buffer[1] = 0; + + return Encode(buffer.Slice(2), out length); + } + + public bool BeginEncode(int statusCode, IEnumerable<KeyValuePair<string, string>> headers, Span<byte> buffer, out int length) + { + _enumerator = headers.GetEnumerator(); + _enumerator.MoveNext(); + + // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#header-prefix + buffer[0] = 0; + buffer[1] = 0; + + var statusCodeLength = EncodeStatusCode(statusCode, buffer.Slice(2)); + var done = Encode(buffer.Slice(statusCodeLength + 2), throwIfNoneEncoded: false, out var headersLength); + length = statusCodeLength + headersLength + 2; + + return done; + } + + public bool Encode(Span<byte> buffer, out int length) + { + return Encode(buffer, throwIfNoneEncoded: true, out length); + } + + private bool Encode(Span<byte> buffer, bool throwIfNoneEncoded, out int length) + { + length = 0; + + do + { + if (!EncodeHeader(_enumerator.Current.Key, _enumerator.Current.Value, buffer.Slice(length), out var headerLength)) + { + if (length == 0 && throwIfNoneEncoded) + { + throw new QPackEncodingException("TODO sync with corefx" /* CoreStrings.HPackErrorNotEnoughBuffer */); + } + return false; + } + + length += headerLength; + } while (_enumerator.MoveNext()); + + return true; + } + + private bool EncodeHeader(string name, string value, Span<byte> buffer, out int length) + { + var i = 0; + length = 0; + + if (buffer.IsEmpty) + { + return false; + } + + if (!EncodeNameString(name, buffer.Slice(i), out var nameLength, lowercase: true)) + { + return false; + } + + i += nameLength; + + if (i >= buffer.Length) + { + return false; + } + + if (!EncodeValueString(value, buffer.Slice(i), out var valueLength, lowercase: false)) + { + return false; + } + + i += valueLength; + + length = i; + return true; + } + + private bool EncodeValueString(string s, Span<byte> buffer, out int length, bool lowercase) + { + const int toLowerMask = 0x20; + + var i = 0; + length = 0; + + if (buffer.IsEmpty) + { + return false; + } + + buffer[0] = 0; + + if (!IntegerEncoder.Encode(s.Length, 7, buffer, out var nameLength)) + { + return false; + } + + i += nameLength; + + // TODO: use huffman encoding + for (var j = 0; j < s.Length; j++) + { + if (i >= buffer.Length) + { + return false; + } + + buffer[i++] = (byte)(s[j] | (lowercase && s[j] >= (byte)'A' && s[j] <= (byte)'Z' ? toLowerMask : 0)); + } + + length = i; + return true; + } + + private bool EncodeNameString(string s, Span<byte> buffer, out int length, bool lowercase) + { + const int toLowerMask = 0x20; + + var i = 0; + length = 0; + + if (buffer.IsEmpty) + { + return false; + } + + buffer[0] = 0x30; + + if (!IntegerEncoder.Encode(s.Length, 3, buffer, out var nameLength)) + { + return false; + } + + i += nameLength; + + // TODO: use huffman encoding + for (var j = 0; j < s.Length; j++) + { + if (i >= buffer.Length) + { + return false; + } + + buffer[i++] = (byte)(s[j] | (lowercase && s[j] >= (byte)'A' && s[j] <= (byte)'Z' ? toLowerMask : 0)); + } + + length = i; + return true; + } + + private int EncodeStatusCode(int statusCode, Span<byte> buffer) + { + switch (statusCode) + { + case 200: + case 204: + case 206: + case 304: + case 400: + case 404: + case 500: + // TODO this isn't safe, some index can be larger than 64. Encoded here! + buffer[0] = (byte)(0xC0 | StaticTable.Instance.StatusIndex[statusCode]); + return 1; + default: + // Send as Literal Header Field Without Indexing - Indexed Name + buffer[0] = 0x08; + + var statusBytes = StatusCodes.ToStatusBytes(statusCode); + buffer[1] = (byte)statusBytes.Length; + ((ReadOnlySpan<byte>)statusBytes).CopyTo(buffer.Slice(2)); + + return 2 + statusBytes.Length; + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecodingException.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackEncodingException.cs similarity index 67% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecodingException.cs rename to src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackEncodingException.cs index d549554ab6..306850ab4b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecodingException.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/QPackEncodingException.cs @@ -3,15 +3,15 @@ using System; -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack { - internal sealed class HPackDecodingException : Exception + internal sealed class QPackEncodingException : Exception { - public HPackDecodingException(string message) + public QPackEncodingException(string message) : base(message) { } - public HPackDecodingException(string message, Exception innerException) + public QPackEncodingException(string message, Exception innerException) : base(message, innerException) { } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/StaticTable.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/StaticTable.cs new file mode 100644 index 0000000000..4bf15a9b45 --- /dev/null +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/QPack/StaticTable.cs @@ -0,0 +1,162 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Net.Http; +using System.Text; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack +{ + internal class StaticTable + { + private static readonly StaticTable _instance = new StaticTable(); + + private readonly Dictionary<int, int> _statusIndex = new Dictionary<int, int> + { + [103] = 24, + [200] = 25, + [304] = 26, + [404] = 27, + [503] = 28, + [100] = 63, + [204] = 64, + [206] = 65, + [302] = 66, + [400] = 67, + [403] = 68, + [421] = 69, + [425] = 70, + [500] = 71, + }; + + private readonly Dictionary<HttpMethod, int> _methodIndex = new Dictionary<HttpMethod, int> + { + // TODO connect is intenral to system.net.http + [HttpMethod.Delete] = 16, + [HttpMethod.Get] = 17, + [HttpMethod.Head] = 18, + [HttpMethod.Options] = 19, + [HttpMethod.Post] = 20, + [HttpMethod.Put] = 21, + }; + + private StaticTable() + { + } + + public static StaticTable Instance => _instance; + + public int Count => _staticTable.Length; + + public HeaderField this[int index] => _staticTable[index]; + + public IReadOnlyDictionary<int, int> StatusIndex => _statusIndex; + public IReadOnlyDictionary<HttpMethod, int> MethodIndex => _methodIndex; + + private readonly HeaderField[] _staticTable = new HeaderField[] + { + CreateHeaderField(":authority", ""), // 0 + CreateHeaderField(":path", "/"), // 1 + CreateHeaderField("age", "0"), // 2 + CreateHeaderField("content-disposition", ""), + CreateHeaderField("content-length", "0"), + CreateHeaderField("cookie", ""), + CreateHeaderField("date", ""), + CreateHeaderField("etag", ""), + CreateHeaderField("if-modified-since", ""), + CreateHeaderField("if-none-match", ""), + CreateHeaderField("last-modified", ""), // 10 + CreateHeaderField("link", ""), + CreateHeaderField("location", ""), + CreateHeaderField("referer", ""), + CreateHeaderField("set-cookie", ""), + CreateHeaderField(":method", "CONNECT"), + CreateHeaderField(":method", "DELETE"), + CreateHeaderField(":method", "GET"), + CreateHeaderField(":method", "HEAD"), + CreateHeaderField(":method", "OPTIONS"), + CreateHeaderField(":method", "POST"), // 20 + CreateHeaderField(":method", "PUT"), + CreateHeaderField(":scheme", "http"), + CreateHeaderField(":scheme", "https"), + CreateHeaderField(":status", "103"), + CreateHeaderField(":status", "200"), + CreateHeaderField(":status", "304"), + CreateHeaderField(":status", "404"), + CreateHeaderField(":status", "503"), + CreateHeaderField("accept", "*/*"), + CreateHeaderField("accept", "application/dns-message"), // 30 + CreateHeaderField("accept-encoding", "gzip, deflate, br"), + CreateHeaderField("accept-ranges", "bytes"), + CreateHeaderField("access-control-allow-headers", "cache-control"), + CreateHeaderField("access-control-allow-origin", "content-type"), + CreateHeaderField("access-control-allow-origin", "*"), + CreateHeaderField("cache-control", "max-age=0"), + CreateHeaderField("cache-control", "max-age=2592000"), + CreateHeaderField("cache-control", "max-age=604800"), + CreateHeaderField("cache-control", "no-cache"), + CreateHeaderField("cache-control", "no-store"), // 40 + CreateHeaderField("cache-control", "public, max-age=31536000"), + CreateHeaderField("content-encoding", "br"), + CreateHeaderField("content-encoding", "gzip"), + CreateHeaderField("content-type", "application/dns-message"), + CreateHeaderField("content-type", "application/javascript"), + CreateHeaderField("content-type", "application/json"), + CreateHeaderField("content-type", "application/x-www-form-urlencoded"), + CreateHeaderField("content-type", "image/gif"), + CreateHeaderField("content-type", "image/jpeg"), + CreateHeaderField("content-type", "image/png"), // 50 + CreateHeaderField("content-type", "text/css"), + CreateHeaderField("content-type", "text/html; charset=utf-8"), + CreateHeaderField("content-type", "text/plain"), + CreateHeaderField("content-type", "text/plain;charset=utf-8"), + CreateHeaderField("range", "bytes=0-"), + CreateHeaderField("strict-transport-security", "max-age=31536000"), + CreateHeaderField("strict-transport-security", "max-age=31536000;includesubdomains"), // TODO confirm spaces here don't matter? + CreateHeaderField("strict-transport-security", "max-age=31536000;includesubdomains; preload"), + CreateHeaderField("vary", "accept-encoding"), + CreateHeaderField("vary", "origin"), // 60 + CreateHeaderField("x-content-type-options", "nosniff"), + CreateHeaderField("x-xss-protection", "1; mode=block"), + CreateHeaderField(":status", "100"), + CreateHeaderField(":status", "204"), + CreateHeaderField(":status", "206"), + CreateHeaderField(":status", "302"), + CreateHeaderField(":status", "400"), + CreateHeaderField(":status", "403"), + CreateHeaderField(":status", "421"), + CreateHeaderField(":status", "425"), // 70 + CreateHeaderField(":status", "500"), + CreateHeaderField("accept-language", ""), + CreateHeaderField("access-control-allow-credentials", "FALSE"), + CreateHeaderField("access-control-allow-credentials", "TRUE"), + CreateHeaderField("access-control-allow-headers", "*"), + CreateHeaderField("access-control-allow-methods", "get"), + CreateHeaderField("access-control-allow-methods", "get, post, options"), + CreateHeaderField("access-control-allow-methods", "options"), + CreateHeaderField("access-control-expose-headers", "content-length"), + CreateHeaderField("access-control-request-headers", "content-type"), // 80 + CreateHeaderField("access-control-request-method", "get"), + CreateHeaderField("access-control-request-method", "post"), + CreateHeaderField("alt-svc", "clear"), + CreateHeaderField("authorization", ""), + CreateHeaderField("content-security-policy", "script-src 'none'; object-src 'none'; base-uri 'none'"), + CreateHeaderField("early-data", "1"), + CreateHeaderField("expect-ct", ""), + CreateHeaderField("forwarded", ""), + CreateHeaderField("if-range", ""), + CreateHeaderField("origin", ""), // 90 + CreateHeaderField("purpose", "prefetch"), + CreateHeaderField("server", ""), + CreateHeaderField("timing-allow-origin", "*"), + CreateHeaderField("upgrading-insecure-requests", "1"), + CreateHeaderField("user-agent", ""), + CreateHeaderField("x-forwarded-for", ""), + CreateHeaderField("x-frame-options", "deny"), + CreateHeaderField("x-frame-options", "sameorigin"), + }; + + private static HeaderField CreateHeaderField(string name, string value) + => new HeaderField(Encoding.ASCII.GetBytes(name), Encoding.ASCII.GetBytes(value)); + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/HttpConnection.cs b/src/Servers/Kestrel/Core/src/Internal/HttpConnection.cs index de8411d7f8..5c92ae816d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/HttpConnection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/HttpConnection.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; +using System.Net; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections.Features; @@ -11,6 +12,7 @@ using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Server.Kestrel.Core.Features; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; @@ -66,13 +68,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal requestProcessor = new Http2Connection(_context); _protocolSelectionState = ProtocolSelectionState.Selected; break; + case HttpProtocols.Http3: + requestProcessor = new Http3Connection(_context); + _protocolSelectionState = ProtocolSelectionState.Selected; + break; case HttpProtocols.None: // An error was already logged in SelectProtocol(), but we should close the connection. break; + default: // SelectProtocol() only returns Http1, Http2 or None. - throw new NotSupportedException($"{nameof(SelectProtocol)} returned something other than Http1, Http2 or None."); - } + throw new NotSupportedException($"{nameof(SelectProtocol)} returned something other than Http1, Http2, Http3 or None."); + } _requestProcessor = requestProcessor; @@ -197,6 +204,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal private HttpProtocols SelectProtocol() { + if (_context.Protocols == HttpProtocols.Http3) + { + return HttpProtocols.Http3; + } + var hasTls = _context.ConnectionFeatures.Get<ITlsConnectionFeature>() != null; var applicationProtocol = _context.ConnectionFeatures.Get<ITlsApplicationProtocolFeature>()?.ApplicationProtocol ?? new ReadOnlyMemory<byte>(); diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/Heartbeat.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/Heartbeat.cs index 7cba84b138..9cf9e2d62e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/Heartbeat.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/Heartbeat.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -18,6 +18,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure private readonly TimeSpan _interval; private Timer _timer; private int _executingOnHeartbeat; + private long _lastHeartbeatTicks; public Heartbeat(IHeartbeatHandler[] callbacks, ISystemClock systemClock, IDebugger debugger, IKestrelTrace trace) { @@ -46,6 +47,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure if (Interlocked.Exchange(ref _executingOnHeartbeat, 1) == 0) { + Volatile.Write(ref _lastHeartbeatTicks, now.Ticks); + try { foreach (var callback in _callbacks) @@ -66,7 +69,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure { if (!_debugger.IsAttached) { - _trace.HeartbeatSlow(_interval, now); + var lastHeartbeatTicks = Volatile.Read(ref _lastHeartbeatTicks); + + _trace.HeartbeatSlow(TimeSpan.FromTicks(now.Ticks - lastHeartbeatTicks), _interval, now); } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs index f57c296e1e..fa3c7803ed 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs @@ -15,6 +15,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure public const string Http10Version = "HTTP/1.0"; public const string Http11Version = "HTTP/1.1"; public const string Http2Version = "HTTP/2"; + public const string Http3Version = "HTTP/3"; public const string HttpUriScheme = "http://"; public const string HttpsUriScheme = "https://"; @@ -85,7 +86,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } // The same as GetAsciiStringNonNullCharacters but throws BadRequest - public static unsafe string GetHeaderName(this Span<byte> span) + public static unsafe string GetHeaderName(this ReadOnlySpan<byte> span) { if (span.IsEmpty) { @@ -108,7 +109,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure return asciiString; } - public static unsafe string GetAsciiStringNonNullCharacters(this Span<byte> span) + public static string GetAsciiStringNonNullCharacters(this Span<byte> span) + => GetAsciiStringNonNullCharacters((ReadOnlySpan<byte>)span); + + public static unsafe string GetAsciiStringNonNullCharacters(this ReadOnlySpan<byte> span) { if (span.IsEmpty) { @@ -131,6 +135,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } public static unsafe string GetAsciiOrUTF8StringNonNullCharacters(this Span<byte> span) + => GetAsciiOrUTF8StringNonNullCharacters((ReadOnlySpan<byte>)span); + + public static unsafe string GetAsciiOrUTF8StringNonNullCharacters(this ReadOnlySpan<byte> span) { if (span.IsEmpty) { diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs index 1a5815300e..cd441ae3a2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net.Http.HPack; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure @@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure void NotAllConnectionsAborted(); - void HeartbeatSlow(TimeSpan interval, DateTimeOffset now); + void HeartbeatSlow(TimeSpan heartbeatDuration, TimeSpan interval, DateTimeOffset now); void ApplicationNeverCompleted(string connectionId); diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs index d72aa3c707..1eac5326e2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net.Http.HPack; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure @@ -47,8 +47,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure private static readonly Action<ILogger, Exception> _notAllConnectionsAborted = LoggerMessage.Define(LogLevel.Debug, new EventId(21, nameof(NotAllConnectionsAborted)), "Some connections failed to abort during server shutdown."); - private static readonly Action<ILogger, TimeSpan, DateTimeOffset, Exception> _heartbeatSlow = - LoggerMessage.Define<TimeSpan, DateTimeOffset>(LogLevel.Warning, new EventId(22, nameof(HeartbeatSlow)), @"Heartbeat took longer than ""{interval}"" at ""{now}"". This could be caused by thread pool starvation."); + private static readonly Action<ILogger, TimeSpan, TimeSpan, DateTimeOffset, Exception> _heartbeatSlow = + LoggerMessage.Define<TimeSpan, TimeSpan, DateTimeOffset>(LogLevel.Warning, new EventId(22, nameof(HeartbeatSlow)), @"As of ""{now}"", the heartbeat has been running for ""{heartbeatDuration}"" which is longer than ""{interval}"". This could be caused by thread pool starvation."); private static readonly Action<ILogger, string, Exception> _applicationNeverCompleted = LoggerMessage.Define<string>(LogLevel.Critical, new EventId(23, nameof(ApplicationNeverCompleted)), @"Connection id ""{ConnectionId}"" application never completed"); @@ -190,9 +190,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure _notAllConnectionsAborted(_logger, null); } - public virtual void HeartbeatSlow(TimeSpan interval, DateTimeOffset now) + public virtual void HeartbeatSlow(TimeSpan heartbeatDuration, TimeSpan interval, DateTimeOffset now) { - _heartbeatSlow(_logger, interval, now, null); + _heartbeatSlow(_logger, heartbeatDuration, interval, now, null); } public virtual void ApplicationNeverCompleted(string connectionId) diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/BufferSegment.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/BufferSegment.cs index fdd8ac7367..a9bf8d9424 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/BufferSegment.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/BufferSegment.cs @@ -59,20 +59,16 @@ namespace System.IO.Pipelines AvailableMemory = arrayPoolBuffer; } - public void SetUnownedMemory(Memory<byte> memory) - { - AvailableMemory = memory; - } - public void ResetMemory() { if (_memoryOwner is IMemoryOwner<byte> owner) { owner.Dispose(); } - else if (_memoryOwner is byte[] array) + else { - ArrayPool<byte>.Shared.Return(array); + byte[] poolArray = (byte[])_memoryOwner; + ArrayPool<byte>.Shared.Return(poolArray); } // Order of below field clears is significant as it clears in a sequential order diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/ConcurrentPipeWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/ConcurrentPipeWriter.cs index 3ab051c8c4..4e09b0a8a4 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/ConcurrentPipeWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/ConcurrentPipeWriter.cs @@ -341,8 +341,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW } else { - // We can't use the pool so allocate an array - newSegment.SetUnownedMemory(new byte[sizeHint]); + // We can't use the recommended pool so use the ArrayPool + newSegment.SetOwnedMemory(ArrayPool<byte>.Shared.Rent(sizeHint)); } _tailMemory = newSegment.AvailableMemory; diff --git a/src/Servers/Kestrel/Core/src/KestrelServer.cs b/src/Servers/Kestrel/Core/src/KestrelServer.cs index 6eb5ada99d..5d1c1b4cee 100644 --- a/src/Servers/Kestrel/Core/src/KestrelServer.cs +++ b/src/Servers/Kestrel/Core/src/KestrelServer.cs @@ -23,26 +23,32 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core { private readonly List<(IConnectionListener, Task)> _transports = new List<(IConnectionListener, Task)>(); private readonly IServerAddressesFeature _serverAddresses; - private readonly IConnectionListenerFactory _transportFactory; + private readonly List<IConnectionListenerFactory> _transportFactories; private bool _hasStarted; private int _stopping; private readonly TaskCompletionSource<object> _stoppedTcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); - public KestrelServer(IOptions<KestrelServerOptions> options, IConnectionListenerFactory transportFactory, ILoggerFactory loggerFactory) - : this(transportFactory, CreateServiceContext(options, loggerFactory)) + public KestrelServer(IOptions<KestrelServerOptions> options, IEnumerable<IConnectionListenerFactory> transportFactories, ILoggerFactory loggerFactory) + : this(transportFactories, CreateServiceContext(options, loggerFactory)) { } // For testing - internal KestrelServer(IConnectionListenerFactory transportFactory, ServiceContext serviceContext) + internal KestrelServer(IEnumerable<IConnectionListenerFactory> transportFactories, ServiceContext serviceContext) { - if (transportFactory == null) + if (transportFactories == null) { - throw new ArgumentNullException(nameof(transportFactory)); + throw new ArgumentNullException(nameof(transportFactories)); + } + + _transportFactories = transportFactories.ToList(); + + if (_transportFactories.Count == 0) + { + throw new InvalidOperationException(CoreStrings.TransportNotFound); } - _transportFactory = transportFactory; ServiceContext = serviceContext; Features = new FeatureCollection(); @@ -135,7 +141,30 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core } var connectionDispatcher = new ConnectionDispatcher(ServiceContext, connectionDelegate); - var transport = await _transportFactory.BindAsync(options.EndPoint).ConfigureAwait(false); + + IConnectionListenerFactory factory = null; + if (options.Protocols >= HttpProtocols.Http3) + { + foreach (var transportFactory in _transportFactories) + { + if (transportFactory is IMultiplexedConnectionListenerFactory) + { + // Don't break early. Always use the last registered factory. + factory = transportFactory; + } + } + + if (factory == null) + { + throw new InvalidOperationException(CoreStrings.QuicTransportNotFound); + } + } + else + { + factory = _transportFactories.Last(); + } + + var transport = await factory.BindAsync(options.EndPoint).ConfigureAwait(false); // Update the endpoint options.EndPoint = transport.EndPoint; diff --git a/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs b/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs index 10db0fe662..46a916e963 100644 --- a/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs +++ b/src/Servers/Kestrel/Core/src/KestrelServerLimits.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -258,6 +258,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core /// </summary> public Http2Limits Http2 { get; } = new Http2Limits(); + /// <summary> + /// Limits only applicable to HTTP/3 connections. + /// </summary> + public Http3Limits Http3 { get; } = new Http3Limits(); + /// <summary> /// Gets or sets the request body minimum data rate in bytes/second. /// Setting this property to null indicates no minimum data rate should be enforced. diff --git a/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs b/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs index c383945c98..19bbce9362 100644 --- a/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs +++ b/src/Servers/Kestrel/Core/src/KestrelServerOptions.cs @@ -72,6 +72,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core /// </summary> public KestrelConfigurationLoader ConfigurationLoader { get; set; } + /// <summary> + /// Controls whether to return the AltSvcHeader from on an HTTP/2 or lower response for HTTP/3 + /// </summary> + public bool EnableAltSvc { get; set; } = false; + /// <summary> /// A default configuration action for all endpoints. Use for Listen, configuration, the default url, and URLs. /// </summary> diff --git a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj index ea3a87bad7..37d8684e99 100644 --- a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj +++ b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <Description>Core components of ASP.NET Core Kestrel cross-platform web server.</Description> @@ -9,12 +9,16 @@ <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <NoWarn>CS1591;$(NoWarn)</NoWarn> <IsShippingPackage>false</IsShippingPackage> + <DefineConstants>$(DefineConstants);KESTREL</DefineConstants> </PropertyGroup> <ItemGroup> <Compile Include="$(SharedSourceRoot)CertificateGeneration\**\*.cs" /> <Compile Include="$(SharedSourceRoot)ValueTaskExtensions\**\*.cs" /> <Compile Include="$(SharedSourceRoot)UrlDecoder\**\*.cs" /> + <Compile Include="$(SharedSourceRoot)Http2\**\*.cs" LinkBase="Shared\Http2\" /> + <Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" /> + <Compile Include="$(RepoRoot)src\Shared\TaskToApm.cs" Link="Internal\TaskToApm.cs" /> </ItemGroup> <ItemGroup> @@ -33,6 +37,14 @@ <EmbeddedResource Update="CoreStrings.resx"> <Generator></Generator> </EmbeddedResource> + <EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx"> + <ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> + <EmbeddedResource Include="$(SharedSourceRoot)Http2\SR.resx" Link="Shared\Http2\SR.resx"> + <ManifestResourceName>System.Net.Http.SR</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> </ItemGroup> </Project> diff --git a/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs b/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs index c3f24b4afd..a568f7a02c 100644 --- a/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs +++ b/src/Servers/Kestrel/Core/src/Middleware/HttpsConnectionMiddleware.cs @@ -77,16 +77,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal } _options = options; - _logger = loggerFactory?.CreateLogger<HttpsConnectionMiddleware>(); - } - public Task OnConnectionAsync(ConnectionContext context) - { - return Task.Run(() => InnerOnConnectionAsync(context)); + _logger = loggerFactory.CreateLogger<HttpsConnectionMiddleware>(); } - private async Task InnerOnConnectionAsync(ConnectionContext context) + public async Task OnConnectionAsync(ConnectionContext context) { + await Task.Yield(); + bool certificateRequired; + if (context.Features.Get<ITlsConnectionFeature>() != null) + { + await _next(context); + return; + } + var feature = new Core.Internal.TlsConnectionFeature(); context.Features.Set<ITlsConnectionFeature>(feature); context.Features.Set<ITlsHandshakeFeature>(feature); @@ -156,7 +160,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal var sslStream = sslDuplexPipe.Stream; using (var cancellationTokeSource = new CancellationTokenSource(_options.HandshakeTimeout)) - using (cancellationTokeSource.Token.UnsafeRegister(state => ((ConnectionContext)state).Abort(), context)) { try { @@ -201,17 +204,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal _options.OnAuthenticate?.Invoke(context, sslOptions); - await sslStream.AuthenticateAsServerAsync(sslOptions, CancellationToken.None); + await sslStream.AuthenticateAsServerAsync(sslOptions, cancellationTokeSource.Token); } catch (OperationCanceledException) { - _logger?.LogDebug(2, CoreStrings.AuthenticationTimedOut); + _logger.LogDebug(2, CoreStrings.AuthenticationTimedOut); await sslStream.DisposeAsync(); return; } catch (IOException ex) { - _logger?.LogDebug(1, ex, CoreStrings.AuthenticationFailed); + _logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed); await sslStream.DisposeAsync(); return; } @@ -221,11 +224,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal !CertificateManager.IsHttpsDevelopmentCertificate(_serverCertificate) || CertificateManager.CheckDeveloperCertificateKey(_serverCertificate)) { - _logger?.LogDebug(1, ex, CoreStrings.AuthenticationFailed); + _logger.LogDebug(1, ex, CoreStrings.AuthenticationFailed); } else { - _logger?.LogError(3, ex, CoreStrings.BadDeveloperCertificateState); + _logger.LogError(3, ex, CoreStrings.BadDeveloperCertificateState); } await sslStream.DisposeAsync(); @@ -288,19 +291,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal return new X509Certificate2(certificate); } - - private class SslDuplexPipe : DuplexPipeStreamAdapter<SslStream> - { - public SslDuplexPipe(IDuplexPipe transport, StreamPipeReaderOptions readerOptions, StreamPipeWriterOptions writerOptions) - : this(transport, readerOptions, writerOptions, s => new SslStream(s)) - { - - } - - public SslDuplexPipe(IDuplexPipe transport, StreamPipeReaderOptions readerOptions, StreamPipeWriterOptions writerOptions, Func<Stream, SslStream> factory) : - base(transport, readerOptions, writerOptions, factory) - { - } - } } } diff --git a/src/Servers/Kestrel/Core/src/Middleware/Internal/LoggingStream.cs b/src/Servers/Kestrel/Core/src/Middleware/Internal/LoggingStream.cs index e3fdec3f81..15758f64f4 100644 --- a/src/Servers/Kestrel/Core/src/Middleware/Internal/LoggingStream.cs +++ b/src/Servers/Kestrel/Core/src/Middleware/Internal/LoggingStream.cs @@ -176,78 +176,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal // The below APM methods call the underlying Read/WriteAsync methods which will still be logged. public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = ReadAsync(buffer, offset, count, default(CancellationToken), state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); } public override int EndRead(IAsyncResult asyncResult) { - return ((Task<int>)asyncResult).GetAwaiter().GetResult(); - } - - private Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<int>(state); - var task = ReadAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<int>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(task2.Result); - } - }, tcs, cancellationToken); - return tcs.Task; + return TaskToApm.End<int>(asyncResult); } public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = WriteAsync(buffer, offset, count, default(CancellationToken), state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); } public override void EndWrite(IAsyncResult asyncResult) { - ((Task<object>)asyncResult).GetAwaiter().GetResult(); - } - - private Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<object>(state); - var task = WriteAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<object>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(null); - } - }, tcs, cancellationToken); - return tcs.Task; + TaskToApm.End(asyncResult); } } } diff --git a/src/Servers/Kestrel/Core/test/AddressBinderTests.cs b/src/Servers/Kestrel/Core/test/AddressBinderTests.cs index b5305f5c1d..d4aaee32b7 100644 --- a/src/Servers/Kestrel/Core/test/AddressBinderTests.cs +++ b/src/Servers/Kestrel/Core/test/AddressBinderTests.cs @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests } [ConditionalFact] - [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)] + [OSSkipCondition(OperatingSystems.Windows, SkipReason = "tmp/kestrel-test.sock is not valid for windows. Unix socket path must be absolute.")] public void ParseAddressUnixPipe() { var listenOptions = AddressBinder.ParseAddress("http://unix:/tmp/kestrel-test.sock", out var https); @@ -86,6 +86,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.False(https); } + [ConditionalFact] + [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX, SkipReason = "Windows has drive letters and volume separator (c:), testing this url on unix or osx provides completely different output.")] + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)] + public void ParseAddressUnixPipeOnWindows() + { + var listenOptions = AddressBinder.ParseAddress(@"http://unix:/c:/foo/bar/pipe.socket", out var https); + Assert.IsType<UnixDomainSocketEndPoint>(listenOptions.EndPoint); + Assert.Equal("c:/foo/bar/pipe.socket", listenOptions.SocketPath); + Assert.False(https); + } + [Theory] [InlineData("http://10.10.10.10:5000/", "10.10.10.10", 5000, false)] [InlineData("http://[::1]:5000", "::1", 5000, false)] diff --git a/src/Servers/Kestrel/Core/test/DynamicTableTests.cs b/src/Servers/Kestrel/Core/test/DynamicTableTests.cs deleted file mode 100644 index a7fb8520c6..0000000000 --- a/src/Servers/Kestrel/Core/test/DynamicTableTests.cs +++ /dev/null @@ -1,174 +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. - -using System; -using System.Linq; -using System.Text; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; -using Xunit; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests -{ - public class DynamicTableTests - { - private readonly HeaderField _header1 = new HeaderField(Encoding.ASCII.GetBytes("header-1"), Encoding.ASCII.GetBytes("value1")); - private readonly HeaderField _header2 = new HeaderField(Encoding.ASCII.GetBytes("header-02"), Encoding.ASCII.GetBytes("value_2")); - - [Fact] - public void DynamicTableIsInitiallyEmpty() - { - var dynamicTable = new DynamicTable(4096); - Assert.Equal(0, dynamicTable.Count); - Assert.Equal(0, dynamicTable.Size); - Assert.Equal(4096, dynamicTable.MaxSize); - } - - [Fact] - public void CountIsNumberOfEntriesInDynamicTable() - { - var dynamicTable = new DynamicTable(4096); - - dynamicTable.Insert(_header1.Name, _header1.Value); - Assert.Equal(1, dynamicTable.Count); - - dynamicTable.Insert(_header2.Name, _header2.Value); - Assert.Equal(2, dynamicTable.Count); - } - - [Fact] - public void SizeIsCurrentDynamicTableSize() - { - var dynamicTable = new DynamicTable(4096); - Assert.Equal(0, dynamicTable.Size); - - dynamicTable.Insert(_header1.Name, _header1.Value); - Assert.Equal(_header1.Length, dynamicTable.Size); - - dynamicTable.Insert(_header2.Name, _header2.Value); - Assert.Equal(_header1.Length + _header2.Length, dynamicTable.Size); - } - - [Fact] - public void FirstEntryIsMostRecentEntry() - { - var dynamicTable = new DynamicTable(4096); - dynamicTable.Insert(_header1.Name, _header1.Value); - dynamicTable.Insert(_header2.Name, _header2.Value); - - VerifyTableEntries(dynamicTable, _header2, _header1); - } - - [Fact] - public void WrapsAroundBuffer() - { - var header3 = new HeaderField(Encoding.ASCII.GetBytes("header-3"), Encoding.ASCII.GetBytes("value3")); - var header4 = new HeaderField(Encoding.ASCII.GetBytes("header-4"), Encoding.ASCII.GetBytes("value4")); - - // Make the table small enough that the circular buffer kicks in. - var dynamicTable = new DynamicTable(HeaderField.RfcOverhead * 3); - dynamicTable.Insert(header4.Name, header4.Value); - dynamicTable.Insert(header3.Name, header3.Value); - dynamicTable.Insert(_header2.Name, _header2.Value); - dynamicTable.Insert(_header1.Name, _header1.Value); - - VerifyTableEntries(dynamicTable, _header1, _header2); - } - - [Fact] - public void ThrowsIndexOutOfRangeException() - { - var dynamicTable = new DynamicTable(4096); - Assert.Throws<IndexOutOfRangeException>(() => dynamicTable[0]); - - dynamicTable.Insert(_header1.Name, _header1.Value); - Assert.Throws<IndexOutOfRangeException>(() => dynamicTable[1]); - } - - [Fact] - public void NoOpWhenInsertingEntryLargerThanMaxSize() - { - var dynamicTable = new DynamicTable(_header1.Length - 1); - dynamicTable.Insert(_header1.Name, _header1.Value); - - Assert.Equal(0, dynamicTable.Count); - Assert.Equal(0, dynamicTable.Size); - } - - [Fact] - public void NoOpWhenInsertingEntryLargerThanRemainingSpace() - { - var dynamicTable = new DynamicTable(_header1.Length); - dynamicTable.Insert(_header1.Name, _header1.Value); - - VerifyTableEntries(dynamicTable, _header1); - - dynamicTable.Insert(_header2.Name, _header2.Value); - - Assert.Equal(0, dynamicTable.Count); - Assert.Equal(0, dynamicTable.Size); - } - - [Fact] - public void ResizingEvictsOldestEntries() - { - var dynamicTable = new DynamicTable(4096); - dynamicTable.Insert(_header1.Name, _header1.Value); - dynamicTable.Insert(_header2.Name, _header2.Value); - - VerifyTableEntries(dynamicTable, _header2, _header1); - - dynamicTable.Resize(_header2.Length); - - VerifyTableEntries(dynamicTable, _header2); - } - - [Fact] - public void ResizingToZeroEvictsAllEntries() - { - var dynamicTable = new DynamicTable(4096); - dynamicTable.Insert(_header1.Name, _header1.Value); - dynamicTable.Insert(_header2.Name, _header2.Value); - - dynamicTable.Resize(0); - - Assert.Equal(0, dynamicTable.Count); - Assert.Equal(0, dynamicTable.Size); - } - - [Fact] - public void CanBeResizedToLargerMaxSize() - { - var dynamicTable = new DynamicTable(_header1.Length); - dynamicTable.Insert(_header1.Name, _header1.Value); - dynamicTable.Insert(_header2.Name, _header2.Value); - - // _header2 is larger than _header1, so an attempt at inserting it - // would first clear the table then return without actually inserting it, - // given it is larger than the current max size. - Assert.Equal(0, dynamicTable.Count); - Assert.Equal(0, dynamicTable.Size); - - dynamicTable.Resize(dynamicTable.MaxSize + _header2.Length); - dynamicTable.Insert(_header2.Name, _header2.Value); - - VerifyTableEntries(dynamicTable, _header2); - } - - private void VerifyTableEntries(DynamicTable dynamicTable, params HeaderField[] entries) - { - Assert.Equal(entries.Length, dynamicTable.Count); - Assert.Equal(entries.Sum(e => e.Length), dynamicTable.Size); - - for (var i = 0; i < entries.Length; i++) - { - var headerField = dynamicTable[i]; - - Assert.NotSame(entries[i].Name, headerField.Name); - Assert.Equal(entries[i].Name, headerField.Name); - - Assert.NotSame(entries[i].Value, headerField.Value); - Assert.Equal(entries[i].Value, headerField.Value); - } - } - } -} diff --git a/src/Servers/Kestrel/Core/test/HPackEncoderTests.cs b/src/Servers/Kestrel/Core/test/HPackEncoderTests.cs index 57ee0ba9a4..b41eb2a910 100644 --- a/src/Servers/Kestrel/Core/test/HPackEncoderTests.cs +++ b/src/Servers/Kestrel/Core/test/HPackEncoderTests.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; +using System.Net.Http.HPack; using Xunit; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests diff --git a/src/Servers/Kestrel/Core/test/HPackIntegerTests.cs b/src/Servers/Kestrel/Core/test/HPackIntegerTests.cs deleted file mode 100644 index 4448463dd4..0000000000 --- a/src/Servers/Kestrel/Core/test/HPackIntegerTests.cs +++ /dev/null @@ -1,91 +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. - -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; -using Xunit; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests -{ - public class HPackIntegerTests - { - [Fact] - public void IntegerEncoderDecoderRoundtrips() - { - var decoder = new IntegerDecoder(); - var range = 1 << 8; - - foreach (var i in Enumerable.Range(0, range).Concat(Enumerable.Range(int.MaxValue - range + 1, range))) - { - for (int n = 1; n <= 8; n++) - { - var integerBytes = new byte[6]; - Assert.True(IntegerEncoder.Encode(i, n, integerBytes, out var length)); - - var decodeResult = decoder.BeginTryDecode(integerBytes[0], n, out var intResult); - - for (int j = 1; j < length; j++) - { - Assert.False(decodeResult); - decodeResult = decoder.TryDecode(integerBytes[j], out intResult); - } - - Assert.True(decodeResult); - Assert.Equal(i, intResult); - } - } - } - - [Theory] - [MemberData(nameof(IntegerCodecSamples))] - public void EncodeSamples(int value, int bits, byte[] expectedResult) - { - Span<byte> actualResult = new byte[64]; - bool success = IntegerEncoder.Encode(value, bits, actualResult, out int bytesWritten); - - Assert.True(success); - Assert.Equal(expectedResult.Length, bytesWritten); - Assert.True(actualResult.Slice(0, bytesWritten).SequenceEqual(expectedResult)); - } - - [Theory] - [MemberData(nameof(IntegerCodecSamples))] - public void EncodeSamplesWithShortBuffer(int value, int bits, byte[] expectedResult) - { - Span<byte> actualResult = new byte[expectedResult.Length - 1]; - bool success = IntegerEncoder.Encode(value, bits, actualResult, out int bytesWritten); - - Assert.False(success); - } - - [Theory] - [MemberData(nameof(IntegerCodecSamples))] - public void DecodeSamples(int expectedResult, int bits, byte[] encoded) - { - var integerDecoder = new IntegerDecoder(); - - bool finished = integerDecoder.BeginTryDecode(encoded[0], bits, out int actualResult); - - int i = 1; - for (; !finished && i < encoded.Length; ++i) - { - finished = integerDecoder.TryDecode(encoded[i], out actualResult); - } - - Assert.True(finished); - Assert.Equal(encoded.Length, i); - - Assert.Equal(expectedResult, actualResult); - } - - // integer, prefix length, encoded - public static IEnumerable<object[]> IntegerCodecSamples() - { - yield return new object[] { 10, 5, new byte[] { 0x0A } }; - yield return new object[] { 1337, 5, new byte[] { 0x1F, 0x9A, 0x0A } }; - yield return new object[] { 42, 8, new byte[] { 0x2A } }; - } - } -} diff --git a/src/Servers/Kestrel/Core/test/HeartbeatTests.cs b/src/Servers/Kestrel/Core/test/HeartbeatTests.cs index f0d4485b3e..bb4e896b44 100644 --- a/src/Servers/Kestrel/Core/test/HeartbeatTests.cs +++ b/src/Servers/Kestrel/Core/test/HeartbeatTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await blockedHeartbeatTask.DefaultTimeout(); heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once()); - kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Once()); + kestrelTrace.Verify(t => t.HeartbeatSlow(TimeSpan.Zero, Heartbeat.Interval, systemClock.UtcNow), Times.Once()); } [Fact] @@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await blockedHeartbeatTask.DefaultTimeout(); heartbeatHandler.Verify(h => h.OnHeartbeat(systemClock.UtcNow), Times.Once()); - kestrelTrace.Verify(t => t.HeartbeatSlow(Heartbeat.Interval, systemClock.UtcNow), Times.Never()); + kestrelTrace.Verify(t => t.HeartbeatSlow(TimeSpan.Zero, Heartbeat.Interval, systemClock.UtcNow), Times.Never()); } [Fact] diff --git a/src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs b/src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs index f602d09798..9db4d37f9c 100644 --- a/src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs +++ b/src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs @@ -751,7 +751,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _http1Connection.Abort(new ConnectionAbortedException()); // The following line will throw an ODE because the original CTS backing the token has been diposed. - // See https://github.com/aspnet/AspNetCore/pull/4447 for the history behind this test. + // See https://github.com/dotnet/aspnetcore/pull/4447 for the history behind this test. //Assert.True(originalToken.WaitHandle.WaitOne(TestConstants.DefaultTimeout)); Assert.True(_http1Connection.RequestAborted.WaitHandle.WaitOne(TestConstants.DefaultTimeout)); diff --git a/src/Servers/Kestrel/Core/test/HttpParserTests.cs b/src/Servers/Kestrel/Core/test/HttpParserTests.cs index 7ce8587743..ebd7bfc316 100644 --- a/src/Servers/Kestrel/Core/test/HttpParserTests.cs +++ b/src/Servers/Kestrel/Core/test/HttpParserTests.cs @@ -1,10 +1,11 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Buffers; using System.Collections.Generic; using System.Linq; +using System.Net.Http; using System.Text; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; @@ -13,6 +14,7 @@ using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; using Moq; using Xunit; +using HttpMethod = Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { @@ -394,6 +396,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal(buffer.End, examined); } + [Fact] + public void ParseRequestLineTlsOverHttp() + { + var parser = CreateParser(_nullTrace); + var buffer = ReadOnlySequenceFactory.CreateSegments(new byte[] { 0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0xfc, 0x03, 0x03, 0x03, 0xca, 0xe0, 0xfd, 0x0a }); + + var requestHandler = new RequestHandler(); + + var badHttpRequestException = Assert.Throws<BadHttpRequestException>(() => + { + parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined); + }); + + Assert.Equal(badHttpRequestException.StatusCode, StatusCodes.Status400BadRequest); + Assert.Equal(RequestRejectionReason.TlsOverHttpError, badHttpRequestException.Reason); + } + [Fact] public void ParseHeadersWithGratuitouslySplitBuffers() { @@ -488,12 +507,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public Dictionary<string, string> Headers { get; } = new Dictionary<string, string>(); - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { Headers[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters(); } - void IHttpHeadersHandler.OnHeadersComplete() { } + void IHttpHeadersHandler.OnHeadersComplete(bool endStream) { } public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded) { diff --git a/src/Servers/Kestrel/Core/test/HttpResponseHeadersTests.cs b/src/Servers/Kestrel/Core/test/HttpResponseHeadersTests.cs index ed3c492e3c..1bbe06e99c 100644 --- a/src/Servers/Kestrel/Core/test/HttpResponseHeadersTests.cs +++ b/src/Servers/Kestrel/Core/test/HttpResponseHeadersTests.cs @@ -138,6 +138,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Throws<InvalidOperationException>(() => ((IDictionary<string, StringValues>)headers).Add("my-header", new[] { "value" })); } + [Fact] + public void ThrowsWhenSettingContentLengthPropertyAfterReadOnlyIsSet() + { + var headers = new HttpResponseHeaders(); + headers.SetReadOnly(); + + Assert.Throws<InvalidOperationException>(() => headers.ContentLength = null); + } + [Fact] public void ThrowsWhenChangingHeaderAfterReadOnlyIsSet() { diff --git a/src/Servers/Kestrel/Core/test/IntegerDecoderTests.cs b/src/Servers/Kestrel/Core/test/IntegerDecoderTests.cs deleted file mode 100644 index fdebb56922..0000000000 --- a/src/Servers/Kestrel/Core/test/IntegerDecoderTests.cs +++ /dev/null @@ -1,86 +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. - -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; -using Xunit; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests -{ - public class IntegerDecoderTests - { - [Theory] - [MemberData(nameof(IntegerData))] - public void IntegerDecode(int i, int prefixLength, byte[] octets) - { - var decoder = new IntegerDecoder(); - var result = decoder.BeginTryDecode(octets[0], prefixLength, out var intResult); - - if (octets.Length == 1) - { - Assert.True(result); - } - else - { - var j = 1; - - for (; j < octets.Length - 1; j++) - { - Assert.False(decoder.TryDecode(octets[j], out intResult)); - } - - Assert.True(decoder.TryDecode(octets[j], out intResult)); - } - - Assert.Equal(i, intResult); - } - - [Theory] - [MemberData(nameof(IntegerData_OverMax))] - public void IntegerDecode_Throws_IfMaxExceeded(int prefixLength, byte[] octets) - { - var decoder = new IntegerDecoder(); - var result = decoder.BeginTryDecode(octets[0], prefixLength, out var intResult); - - for (var j = 1; j < octets.Length - 1; j++) - { - Assert.False(decoder.TryDecode(octets[j], out intResult)); - } - - Assert.Throws<HPackDecodingException>(() => decoder.TryDecode(octets[octets.Length - 1], out intResult)); - } - - public static TheoryData<int, int, byte[]> IntegerData - { - get - { - var data = new TheoryData<int, int, byte[]>(); - - data.Add(10, 5, new byte[] { 10 }); - data.Add(1337, 5, new byte[] { 0x1f, 0x9a, 0x0a }); - data.Add(42, 8, new byte[] { 42 }); - data.Add(7, 3, new byte[] { 0x7, 0x0 }); - data.Add(int.MaxValue, 1, new byte[] { 0x01, 0xfe, 0xff, 0xff, 0xff, 0x07 }); - data.Add(int.MaxValue, 8, new byte[] { 0xff, 0x80, 0xfe, 0xff, 0xff, 0x07 }); - - return data; - } - } - - public static TheoryData<int, byte[]> IntegerData_OverMax - { - get - { - var data = new TheoryData<int, byte[]>(); - - data.Add(1, new byte[] { 0x01, 0xff, 0xff, 0xff, 0xff, 0x07 }); // Int32.MaxValue + 1 - data.Add(1, new byte[] { 0x01, 0xff, 0xff, 0xff, 0xff, 0x08 }); // MSB exceeds maximum - data.Add(1, new byte[] { 0x01, 0xff, 0xff, 0xff, 0xff, 0x80 }); // Undefined since continuation bit set - data.Add(8, new byte[] { 0xff, 0x81, 0xfe, 0xff, 0xff, 0x07 }); // Int32.MaxValue + 1 - data.Add(8, new byte[] { 0xff, 0x81, 0xfe, 0xff, 0xff, 0x08 }); // MSB exceeds maximum - data.Add(8, new byte[] { 0xff, 0x81, 0xfe, 0xff, 0xff, 0x80 }); // Undefined since continuation bit set - - return data; - } - } - } -} diff --git a/src/Servers/Kestrel/Core/test/IntegerEncoderTests.cs b/src/Servers/Kestrel/Core/test/IntegerEncoderTests.cs deleted file mode 100644 index c667cc6cee..0000000000 --- a/src/Servers/Kestrel/Core/test/IntegerEncoderTests.cs +++ /dev/null @@ -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. - -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; -using Xunit; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests -{ - public class IntegerEncoderTests - { - [Theory] - [MemberData(nameof(IntegerData))] - public void IntegerEncode(int i, int prefixLength, byte[] expectedOctets) - { - var buffer = new byte[expectedOctets.Length]; - - Assert.True(IntegerEncoder.Encode(i, prefixLength, buffer, out var octets)); - Assert.Equal(expectedOctets.Length, octets); - Assert.Equal(expectedOctets, buffer); - } - - public static TheoryData<int, int, byte[]> IntegerData - { - get - { - var data = new TheoryData<int, int, byte[]>(); - - data.Add(10, 5, new byte[] { 10 }); - data.Add(1337, 5, new byte[] { 0x1f, 0x9a, 0x0a }); - data.Add(42, 8, new byte[] { 42 }); - - return data; - } - } - } -} diff --git a/src/Servers/Kestrel/Core/test/KestrelServerTests.cs b/src/Servers/Kestrel/Core/test/KestrelServerTests.cs index 36add68a21..56454bb7a4 100644 --- a/src/Servers/Kestrel/Core/test/KestrelServerTests.cs +++ b/src/Servers/Kestrel/Core/test/KestrelServerTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; @@ -203,20 +204,43 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var mockLoggerFactory = new Mock<ILoggerFactory>(); var mockLogger = new Mock<ILogger>(); mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object); - new KestrelServer(Options.Create<KestrelServerOptions>(null), Mock.Of<IConnectionListenerFactory>(), mockLoggerFactory.Object); + new KestrelServer(Options.Create<KestrelServerOptions>(null), new List<IConnectionListenerFactory>() { new MockTransportFactory() }, mockLoggerFactory.Object); mockLoggerFactory.Verify(factory => factory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel")); } [Fact] - public void StartWithNoTransportFactoryThrows() + public void ConstructorWithNullTransportFactoriesThrows() { - var mockLoggerFactory = new Mock<ILoggerFactory>(); - var mockLogger = new Mock<ILogger>(); - mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object); var exception = Assert.Throws<ArgumentNullException>(() => - new KestrelServer(Options.Create<KestrelServerOptions>(null), null, mockLoggerFactory.Object)); + new KestrelServer( + Options.Create<KestrelServerOptions>(null), + null, + new LoggerFactory(new[] { new KestrelTestLoggerProvider() }))); - Assert.Equal("transportFactory", exception.ParamName); + Assert.Equal("transportFactories", exception.ParamName); + } + + [Fact] + public void ConstructorWithNoTransportFactoriesThrows() + { + var exception = Assert.Throws<InvalidOperationException>(() => + new KestrelServer( + Options.Create<KestrelServerOptions>(null), + new List<IConnectionListenerFactory>(), + new LoggerFactory(new[] { new KestrelTestLoggerProvider() }))); + + Assert.Equal(CoreStrings.TransportNotFound, exception.Message); + } + + [Fact] + public void StartWithMultipleTransportFactoriesDoesNotThrow() + { + using var server = new KestrelServer( + Options.Create(CreateServerOptions()), + new List<IConnectionListenerFactory>() { new ThrowingTransportFactory(), new MockTransportFactory() }, + new LoggerFactory(new[] { new KestrelTestLoggerProvider() })); + + StartDummyApplication(server); } [Fact] @@ -257,7 +281,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var mockLoggerFactory = new Mock<ILoggerFactory>(); var mockLogger = new Mock<ILogger>(); mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object); - var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, mockLoggerFactory.Object); + var server = new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { mockTransportFactory.Object }, mockLoggerFactory.Object); await server.StartAsync(new DummyApplication(), CancellationToken.None); var stopTask1 = server.StopAsync(default); @@ -315,7 +339,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var mockLoggerFactory = new Mock<ILoggerFactory>(); var mockLogger = new Mock<ILogger>(); mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object); - var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, mockLoggerFactory.Object); + var server = new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { mockTransportFactory.Object }, mockLoggerFactory.Object); await server.StartAsync(new DummyApplication(), CancellationToken.None); var stopTask1 = server.StopAsync(default); @@ -370,7 +394,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var mockLoggerFactory = new Mock<ILoggerFactory>(); var mockLogger = new Mock<ILogger>(); mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object); - var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, mockLoggerFactory.Object); + var server = new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { mockTransportFactory.Object }, mockLoggerFactory.Object); await server.StartAsync(new DummyApplication(), default); var stopTask1 = server.StopAsync(default); @@ -416,7 +440,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests DebuggerWrapper.Singleton, testContext.Log); - using (var server = new KestrelServer(new MockTransportFactory(), testContext)) + using (var server = new KestrelServer(new List<IConnectionListenerFactory>() { new MockTransportFactory() }, testContext)) { Assert.Null(testContext.DateHeaderValueManager.GetDateHeaderValues()); @@ -433,12 +457,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests private static KestrelServer CreateServer(KestrelServerOptions options, ILogger testLogger) { - return new KestrelServer(Options.Create(options), new MockTransportFactory(), new LoggerFactory(new[] { new KestrelTestLoggerProvider(testLogger) })); + return new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { new MockTransportFactory() }, new LoggerFactory(new[] { new KestrelTestLoggerProvider(testLogger) })); } private static KestrelServer CreateServer(KestrelServerOptions options, bool throwOnCriticalErrors = true) { - return new KestrelServer(Options.Create(options), new MockTransportFactory(), new LoggerFactory(new[] { new KestrelTestLoggerProvider(throwOnCriticalErrors) })); + return new KestrelServer(Options.Create(options), new List<IConnectionListenerFactory>() { new MockTransportFactory() }, new LoggerFactory(new[] { new KestrelTestLoggerProvider(throwOnCriticalErrors) })); } private static void StartDummyApplication(IServer server) @@ -455,5 +479,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests return new ValueTask<IConnectionListener>(mock.Object); } } + + private class ThrowingTransportFactory : IConnectionListenerFactory + { + public ValueTask<IConnectionListener> BindAsync(EndPoint endpoint, CancellationToken cancellationToken = default) + { + throw new InvalidOperationException(); + } + } } } diff --git a/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj b/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj index 0497c91342..32d1139d42 100644 --- a/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj +++ b/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj @@ -1,9 +1,10 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <TestGroupName>Kestrel.Core.Tests</TestGroupName> + <DefineConstants>$(DefineConstants);KESTREL</DefineConstants> </PropertyGroup> <ItemGroup> @@ -13,8 +14,8 @@ <Compile Include="$(KestrelSharedSourceRoot)KnownHeaders.cs" LinkBase="shared" /> <Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" /> <Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" /> - <Compile Include="$(KestrelSharedSourceRoot)\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" /> + <Compile Include="$(SharedSourceRoot)test\Shared.Tests\Http2\**\*.cs" Link="Shared\Http2\%(Filename)%(Extension)" /> </ItemGroup> <ItemGroup> diff --git a/src/Servers/Kestrel/Core/test/TimeoutControlTests.cs b/src/Servers/Kestrel/Core/test/TimeoutControlTests.cs index 170d7b1479..9477729e3a 100644 --- a/src/Servers/Kestrel/Core/test/TimeoutControlTests.cs +++ b/src/Servers/Kestrel/Core/test/TimeoutControlTests.cs @@ -328,7 +328,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // Read 0 bytes in 1 second now += TimeSpan.FromSeconds(1); - _timeoutControl.Tick(now);; + _timeoutControl.Tick(now); // Timed out _mockTimeoutHandler.Verify(h => h.OnTimeout(TimeoutReason.ReadDataRate), Times.Once); diff --git a/src/Servers/Kestrel/Core/test/VariableIntHelperTests.cs b/src/Servers/Kestrel/Core/test/VariableIntHelperTests.cs new file mode 100644 index 0000000000..e35ad26b98 --- /dev/null +++ b/src/Servers/Kestrel/Core/test/VariableIntHelperTests.cs @@ -0,0 +1,46 @@ +using System; +using System.Buffers; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3; +using Xunit; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests +{ + public class VariableIntHelperTests + { + [Theory] + [MemberData(nameof(IntegerData))] + public void CheckDecoding(long expected, byte[] input) + { + var decoded = VariableLengthIntegerHelper.GetInteger(new ReadOnlySequence<byte>(input), out _, out _); + Assert.Equal(expected, decoded); + } + + [Theory] + [MemberData(nameof(IntegerData))] + public void CheckEncoding(long input, byte[] expected) + { + var outputBuffer = new Span<byte>(new byte[8]); + var encodedLength = VariableLengthIntegerHelper.WriteInteger(outputBuffer, input); + Assert.Equal(expected.Length, encodedLength); + for(var i = 0; i < expected.Length; i++) + { + Assert.Equal(expected[i], outputBuffer[i]); + } + } + + public static TheoryData<long, byte[]> IntegerData + { + get + { + var data = new TheoryData<long, byte[]>(); + + data.Add(151288809941952652, new byte[] { 0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c }); + data.Add(494878333, new byte[] { 0x9d, 0x7f, 0x3e, 0x7d }); + data.Add(15293, new byte[] { 0x7b, 0xbd }); + data.Add(37, new byte[] { 0x25 }); + + return data; + } + } + } +} diff --git a/src/Servers/Kestrel/Kestrel.sln b/src/Servers/Kestrel/Kestrel.sln index 5f7b931878..2c80bcef71 100644 --- a/src/Servers/Kestrel/Kestrel.sln +++ b/src/Servers/Kestrel/Kestrel.sln @@ -82,6 +82,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Hostin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebUtilities", "..\..\Http\WebUtilities\src\Microsoft.AspNetCore.WebUtilities.csproj", "{EE45763C-753D-4228-8E5D-A71F8BDB3D89}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "http2cat", "samples\http2cat\http2cat.csproj", "{3D6821F5-F242-4828-8DDE-89488E85512D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuicSampleApp", "samples\QuicSampleApp\QuicSampleApp.csproj", "{53A8634C-DFC5-4A5B-8864-9EF1707E3F18}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic", "Transport.MsQuic\src\Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj", "{62CFF861-807E-43F6-9403-22AA7F06C9A6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuicSampleClient", "samples\QuicSampleClient\QuicSampleClient.csproj", "{F39A942B-85A8-4C1B-A5BC-435555E79F20}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Http3SampleApp", "samples\Http3SampleApp\Http3SampleApp.csproj", "{B3CDC83A-A9C5-45DF-9828-6BC419C24308}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -452,6 +462,66 @@ Global {EE45763C-753D-4228-8E5D-A71F8BDB3D89}.Release|x64.Build.0 = Release|Any CPU {EE45763C-753D-4228-8E5D-A71F8BDB3D89}.Release|x86.ActiveCfg = Release|Any CPU {EE45763C-753D-4228-8E5D-A71F8BDB3D89}.Release|x86.Build.0 = Release|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Debug|x64.Build.0 = Debug|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Debug|x86.Build.0 = Debug|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Release|Any CPU.Build.0 = Release|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Release|x64.ActiveCfg = Release|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Release|x64.Build.0 = Release|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Release|x86.ActiveCfg = Release|Any CPU + {3D6821F5-F242-4828-8DDE-89488E85512D}.Release|x86.Build.0 = Release|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Debug|x64.ActiveCfg = Debug|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Debug|x64.Build.0 = Debug|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Debug|x86.ActiveCfg = Debug|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Debug|x86.Build.0 = Debug|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Release|Any CPU.Build.0 = Release|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Release|x64.ActiveCfg = Release|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Release|x64.Build.0 = Release|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Release|x86.ActiveCfg = Release|Any CPU + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18}.Release|x86.Build.0 = Release|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Debug|x64.ActiveCfg = Debug|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Debug|x64.Build.0 = Debug|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Debug|x86.ActiveCfg = Debug|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Debug|x86.Build.0 = Debug|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Release|Any CPU.Build.0 = Release|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Release|x64.ActiveCfg = Release|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Release|x64.Build.0 = Release|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Release|x86.ActiveCfg = Release|Any CPU + {62CFF861-807E-43F6-9403-22AA7F06C9A6}.Release|x86.Build.0 = Release|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Debug|x64.ActiveCfg = Debug|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Debug|x64.Build.0 = Debug|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Debug|x86.ActiveCfg = Debug|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Debug|x86.Build.0 = Debug|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Release|Any CPU.Build.0 = Release|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Release|x64.ActiveCfg = Release|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Release|x64.Build.0 = Release|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Release|x86.ActiveCfg = Release|Any CPU + {F39A942B-85A8-4C1B-A5BC-435555E79F20}.Release|x86.Build.0 = Release|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Debug|x64.ActiveCfg = Debug|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Debug|x64.Build.0 = Debug|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Debug|x86.ActiveCfg = Debug|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Debug|x86.Build.0 = Debug|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Release|Any CPU.Build.0 = Release|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Release|x64.ActiveCfg = Release|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Release|x64.Build.0 = Release|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Release|x86.ActiveCfg = Release|Any CPU + {B3CDC83A-A9C5-45DF-9828-6BC419C24308}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -488,6 +558,11 @@ Global {D9872E91-EF1D-4181-82C9-584224ADE368} = {F0A1281A-B512-49D2-8362-21EE32B3674F} {E0AD50A3-2518-4060-8BB9-5649B04B3A6D} = {F0A1281A-B512-49D2-8362-21EE32B3674F} {EE45763C-753D-4228-8E5D-A71F8BDB3D89} = {F0A1281A-B512-49D2-8362-21EE32B3674F} + {3D6821F5-F242-4828-8DDE-89488E85512D} = {F826BA61-60A9-45B6-AF29-FD1A6E313EF0} + {53A8634C-DFC5-4A5B-8864-9EF1707E3F18} = {F826BA61-60A9-45B6-AF29-FD1A6E313EF0} + {62CFF861-807E-43F6-9403-22AA7F06C9A6} = {2B456D08-F72B-4EB8-B663-B6D78FC04BF8} + {F39A942B-85A8-4C1B-A5BC-435555E79F20} = {F826BA61-60A9-45B6-AF29-FD1A6E313EF0} + {B3CDC83A-A9C5-45DF-9828-6BC419C24308} = {F826BA61-60A9-45B6-AF29-FD1A6E313EF0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {48207B50-7D05-4B10-B585-890FE0F4FCE1} diff --git a/src/Servers/Kestrel/Kestrel/test/GeneratedCodeTests.cs b/src/Servers/Kestrel/Kestrel/test/GeneratedCodeTests.cs index 67969b30f5..0b1a191665 100644 --- a/src/Servers/Kestrel/Kestrel/test/GeneratedCodeTests.cs +++ b/src/Servers/Kestrel/Kestrel/test/GeneratedCodeTests.cs @@ -16,14 +16,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2223", FlakyOn.Helix.All)] public void GeneratedCodeIsUpToDate() { - var httpHeadersGeneratedPath = Path.Combine(AppContext.BaseDirectory,"shared", "GeneratedContent", "HttpHeaders.Generated.cs"); - var httpProtocolGeneratedPath = Path.Combine(AppContext.BaseDirectory,"shared", "GeneratedContent", "HttpProtocol.Generated.cs"); - var httpUtilitiesGeneratedPath = Path.Combine(AppContext.BaseDirectory,"shared", "GeneratedContent", "HttpUtilities.Generated.cs"); - var transportConnectionGeneratedPath = Path.Combine(AppContext.BaseDirectory,"shared", "GeneratedContent", "TransportConnection.Generated.cs"); + var httpHeadersGeneratedPath = Path.Combine(AppContext.BaseDirectory, "shared", "GeneratedContent", "HttpHeaders.Generated.cs"); + var httpProtocolGeneratedPath = Path.Combine(AppContext.BaseDirectory, "shared", "GeneratedContent", "HttpProtocol.Generated.cs"); + var httpUtilitiesGeneratedPath = Path.Combine(AppContext.BaseDirectory, "shared", "GeneratedContent", "HttpUtilities.Generated.cs"); + var http2ConnectionGeneratedPath = Path.Combine(AppContext.BaseDirectory, "shared", "GeneratedContent", "Http2Connection.Generated.cs"); + var transportConnectionGeneratedPath = Path.Combine(AppContext.BaseDirectory, "shared", "GeneratedContent", "TransportConnection.Generated.cs"); var testHttpHeadersGeneratedPath = Path.GetTempFileName(); var testHttpProtocolGeneratedPath = Path.GetTempFileName(); var testHttpUtilitiesGeneratedPath = Path.GetTempFileName(); + var testHttp2ConnectionGeneratedPath = Path.GetTempFileName(); var testTransportConnectionGeneratedPath = Path.GetTempFileName(); try @@ -31,26 +33,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests var currentHttpHeadersGenerated = File.ReadAllText(httpHeadersGeneratedPath); var currentHttpProtocolGenerated = File.ReadAllText(httpProtocolGeneratedPath); var currentHttpUtilitiesGenerated = File.ReadAllText(httpUtilitiesGeneratedPath); + var currentHttp2ConnectionGenerated = File.ReadAllText(http2ConnectionGeneratedPath); var currentTransportConnectionGenerated = File.ReadAllText(transportConnectionGeneratedPath); - CodeGenerator.Program.Run(testHttpHeadersGeneratedPath, testHttpProtocolGeneratedPath, testHttpUtilitiesGeneratedPath, testTransportConnectionGeneratedPath); + CodeGenerator.Program.Run(testHttpHeadersGeneratedPath, testHttpProtocolGeneratedPath, testHttpUtilitiesGeneratedPath, testTransportConnectionGeneratedPath, testHttp2ConnectionGeneratedPath); var testHttpHeadersGenerated = File.ReadAllText(testHttpHeadersGeneratedPath); var testHttpProtocolGenerated = File.ReadAllText(testHttpProtocolGeneratedPath); var testHttpUtilitiesGenerated = File.ReadAllText(testHttpUtilitiesGeneratedPath); + var testHttp2ConnectionGenerated = File.ReadAllText(testHttp2ConnectionGeneratedPath); var testTransportConnectionGenerated = File.ReadAllText(testTransportConnectionGeneratedPath); Assert.Equal(currentHttpHeadersGenerated, testHttpHeadersGenerated, ignoreLineEndingDifferences: true); Assert.Equal(currentHttpProtocolGenerated, testHttpProtocolGenerated, ignoreLineEndingDifferences: true); Assert.Equal(currentHttpUtilitiesGenerated, testHttpUtilitiesGenerated, ignoreLineEndingDifferences: true); + Assert.Equal(currentHttp2ConnectionGenerated, testHttp2ConnectionGenerated, ignoreLineEndingDifferences: true); Assert.Equal(currentTransportConnectionGenerated, testTransportConnectionGenerated, ignoreLineEndingDifferences: true); - } finally { File.Delete(testHttpHeadersGeneratedPath); File.Delete(testHttpProtocolGeneratedPath); File.Delete(testHttpUtilitiesGeneratedPath); + File.Delete(testHttp2ConnectionGeneratedPath); File.Delete(testTransportConnectionGeneratedPath); } } diff --git a/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationBuilderTests.cs b/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationBuilderTests.cs index 5a47957cdf..b2425f7175 100644 --- a/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationBuilderTests.cs +++ b/src/Servers/Kestrel/Kestrel/test/KestrelConfigurationBuilderTests.cs @@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests // [InlineData("http2", HttpProtocols.Http2)] // Not supported due to missing ALPN support. https://github.com/dotnet/corefx/issues/33016 [InlineData("http1AndHttp2", HttpProtocols.Http1AndHttp2)] // Gracefully falls back to HTTP/1 [OSSkipCondition(OperatingSystems.Linux)] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win10, WindowsVersions.Win81)] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] public void DefaultConfigSectionCanSetProtocols_MacAndWin7(string input, HttpProtocols expected) => DefaultConfigSectionCanSetProtocols(input, expected); @@ -389,7 +389,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Tests // [InlineData("http2", HttpProtocols.Http2)] // Not supported due to missing ALPN support. https://github.com/dotnet/corefx/issues/33016 [InlineData("http1AndHttp2", HttpProtocols.Http1AndHttp2)] // Gracefully falls back to HTTP/1 [OSSkipCondition(OperatingSystems.Linux)] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win10, WindowsVersions.Win81)] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] public void EndpointConfigSectionCanSetProtocols_MacAndWin7(string input, HttpProtocols expected) => EndpointConfigSectionCanSetProtocols(input, expected); diff --git a/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj b/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj index cade793bc2..33eda7eb1b 100644 --- a/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj +++ b/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj @@ -12,6 +12,7 @@ <Content Include="$(KestrelRoot)Core\src\Internal\Http\HttpHeaders.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" /> <Content Include="$(KestrelRoot)Core\src\Internal\Http\HttpProtocol.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" /> <Content Include="$(KestrelRoot)Core\src\Internal\Infrastructure\HttpUtilities.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" /> + <Content Include="$(KestrelRoot)Core\src\Internal\Http2\Http2Connection.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" /> <Content Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" LinkBase="shared\GeneratedContent" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> diff --git a/src/Servers/Kestrel/Transport.Libuv/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.netcoreapp.cs b/src/Servers/Kestrel/Transport.Libuv/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.netcoreapp.cs index f24337e79d..f680b14300 100644 --- a/src/Servers/Kestrel/Transport.Libuv/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.netcoreapp.cs +++ b/src/Servers/Kestrel/Transport.Libuv/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.netcoreapp.cs @@ -14,9 +14,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv public partial class LibuvTransportOptions { public LibuvTransportOptions() { } - public long? MaxReadBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long? MaxWriteBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool NoDelay { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int ThreadCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Backlog { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaxReadBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaxWriteBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool NoDelay { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int ThreadCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvConstants.cs b/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvConstants.cs index 0e07f1a69c..1e5b7bb75b 100644 --- a/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvConstants.cs +++ b/src/Servers/Kestrel/Transport.Libuv/src/Internal/LibuvConstants.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Runtime.CompilerServices; @@ -8,8 +8,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal { internal static class LibuvConstants { - public const int ListenBacklog = 128; - public const int EOF = -4095; public static readonly int? ECONNRESET = GetECONNRESET(); public static readonly int? EADDRINUSE = GetEADDRINUSE(); diff --git a/src/Servers/Kestrel/Transport.Libuv/src/Internal/Listener.cs b/src/Servers/Kestrel/Transport.Libuv/src/Internal/Listener.cs index 9dc11a31a4..6279764101 100644 --- a/src/Servers/Kestrel/Transport.Libuv/src/Internal/Listener.cs +++ b/src/Servers/Kestrel/Transport.Libuv/src/Internal/Listener.cs @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal return Thread.PostAsync(listener => { listener.ListenSocket = listener.CreateListenSocket(); - listener.ListenSocket.Listen(LibuvConstants.ListenBacklog, ConnectionCallback, listener); + listener.ListenSocket.Listen(TransportContext.Options.Backlog, ConnectionCallback, listener); }, this); } diff --git a/src/Servers/Kestrel/Transport.Libuv/src/Internal/ListenerPrimary.cs b/src/Servers/Kestrel/Transport.Libuv/src/Internal/ListenerPrimary.cs index acbc356294..070ee5a73b 100644 --- a/src/Servers/Kestrel/Transport.Libuv/src/Internal/ListenerPrimary.cs +++ b/src/Servers/Kestrel/Transport.Libuv/src/Internal/ListenerPrimary.cs @@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal ListenPipe = new UvPipeHandle(Log); ListenPipe.Init(Thread.Loop, Thread.QueueCloseHandle, false); ListenPipe.Bind(_pipeName); - ListenPipe.Listen(LibuvConstants.ListenBacklog, + ListenPipe.Listen(TransportContext.Options.Backlog, (pipe, status, error, state) => ((ListenerPrimary)state).OnListenPipe(pipe, status, error), this); } @@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal { // This is an unexpected immediate termination of the dispatch pipe most likely caused by an // external process scanning the pipe, so don't we don't log it too severely. - // https://github.com/aspnet/AspNetCore/issues/4741 + // https://github.com/dotnet/aspnetcore/issues/4741 dispatchPipe.Dispose(); _bufHandle.Free(); diff --git a/src/Servers/Kestrel/Transport.Libuv/src/LibuvTransportOptions.cs b/src/Servers/Kestrel/Transport.Libuv/src/LibuvTransportOptions.cs index 06c8aec796..0aa477f3af 100644 --- a/src/Servers/Kestrel/Transport.Libuv/src/LibuvTransportOptions.cs +++ b/src/Servers/Kestrel/Transport.Libuv/src/LibuvTransportOptions.cs @@ -27,6 +27,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv /// </remarks> public bool NoDelay { get; set; } = true; + /// <summary> + /// The maximum length of the pending connection queue. + /// </summary> + /// <remarks> + /// Defaults to 128. + /// </remarks> + public int Backlog { get; set; } = 128; + public long? MaxReadBufferSize { get; set; } = 1024 * 1024; public long? MaxWriteBufferSize { get; set; } = 64 * 1024; diff --git a/src/Servers/Kestrel/Transport.Libuv/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.csproj b/src/Servers/Kestrel/Transport.Libuv/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.csproj index 3fc89b9e9f..dc7a76c818 100644 --- a/src/Servers/Kestrel/Transport.Libuv/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.csproj +++ b/src/Servers/Kestrel/Transport.Libuv/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.csproj @@ -13,7 +13,7 @@ <ItemGroup> <Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" /> <Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" /> - <Compile Include="$(KestrelSharedSourceRoot)\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> + <Compile Include="$(SharedSourceRoot)ServerInfrastructure\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" Link="Internal\TransportConnection.Generated.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.FeatureCollection.cs" Link="Internal\TransportConnection.FeatureCollection.cs" /> diff --git a/src/Servers/Kestrel/Transport.Libuv/test/LibuvOutputConsumerTests.cs b/src/Servers/Kestrel/Transport.Libuv/test/LibuvOutputConsumerTests.cs index 03c24d661a..77fa96d008 100644 --- a/src/Servers/Kestrel/Transport.Libuv/test/LibuvOutputConsumerTests.cs +++ b/src/Servers/Kestrel/Transport.Libuv/test/LibuvOutputConsumerTests.cs @@ -606,7 +606,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests Assert.True(task3Success.IsCompleted); Assert.False(task3Success.IsCanceled); - Assert.False(task3Success.IsFaulted);; + Assert.False(task3Success.IsFaulted); } }); } diff --git a/src/Servers/Kestrel/Transport.MsQuic/README.md b/src/Servers/Kestrel/Transport.MsQuic/README.md new file mode 100644 index 0000000000..efacbcb9fa --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/README.md @@ -0,0 +1,10 @@ +## Using MsQuic on Windows + +### Setup pre-requisites + +1. Update machine to the latest Windows Insiders build (build number 19010 or later). This is required for TLS 1.3 support. +2. Copy msquic.dll and msquic.pdb to this directory and uncomment the copy task in Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj. This will copy the msquic.dll into any built project. + +For external contributors, msquic.dll isn't available publicly yet. See https://github.com/aspnet/Announcements/issues/393. + +Credit to Diwakar Mantha and the Kaizala team for the MsQuic interop code. \ No newline at end of file diff --git a/src/Servers/Kestrel/Transport.MsQuic/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj b/src/Servers/Kestrel/Transport.MsQuic/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj new file mode 100644 index 0000000000..d75fa659ea --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj @@ -0,0 +1,13 @@ +<!-- This file is automatically generated. --> +<Project Sdk="Microsoft.NET.Sdk"> + <PropertyGroup> + <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks> + </PropertyGroup> + <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'"> + <Compile Include="Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.netcoreapp.cs" /> + <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions" /> + <Reference Include="Microsoft.AspNetCore.Connections.Abstractions" /> + <Reference Include="Microsoft.Extensions.Logging.Abstractions" /> + <Reference Include="Microsoft.Extensions.Options" /> + </ItemGroup> +</Project> diff --git a/src/Servers/Kestrel/Transport.MsQuic/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.netcoreapp.cs b/src/Servers/Kestrel/Transport.MsQuic/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.netcoreapp.cs new file mode 100644 index 0000000000..979742fbd3 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.netcoreapp.cs @@ -0,0 +1,38 @@ +// 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. + +namespace Microsoft.AspNetCore.Hosting +{ + public static partial class WebHostBuilderMsQuicExtensions + { + public static Microsoft.AspNetCore.Hosting.IWebHostBuilder UseMsQuic(this Microsoft.AspNetCore.Hosting.IWebHostBuilder hostBuilder) { throw null; } + public static Microsoft.AspNetCore.Hosting.IWebHostBuilder UseMsQuic(this Microsoft.AspNetCore.Hosting.IWebHostBuilder hostBuilder, System.Action<Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.MsQuicTransportOptions> configureOptions) { throw null; } + } +} +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic +{ + public partial class MsQuicConnectionFactory : Microsoft.AspNetCore.Connections.IConnectionFactory + { + public MsQuicConnectionFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.MsQuicTransportOptions> options, Microsoft.Extensions.Hosting.IHostApplicationLifetime lifetime, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } + [System.Diagnostics.DebuggerStepThroughAttribute] + public System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> ConnectAsync(System.Net.EndPoint endPoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public partial class MsQuicTransportFactory : Microsoft.AspNetCore.Connections.IConnectionListenerFactory, Microsoft.AspNetCore.Connections.IMultiplexedConnectionListenerFactory + { + public MsQuicTransportFactory(Microsoft.Extensions.Hosting.IHostApplicationLifetime applicationLifetime, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.MsQuicTransportOptions> options) { } + [System.Diagnostics.DebuggerStepThroughAttribute] + public System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.IConnectionListener> BindAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public partial class MsQuicTransportOptions + { + public MsQuicTransportOptions() { } + public string Alpn { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan IdleTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public ushort MaxBidirectionalStreamCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaxReadBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public ushort MaxUnidirectionalStreamCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaxWriteBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string RegistrationName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/IMsQuicTrace.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/IMsQuicTrace.cs new file mode 100644 index 0000000000..07c2cf0436 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/IMsQuicTrace.cs @@ -0,0 +1,16 @@ +// 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 Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal interface IMsQuicTrace : ILogger + { + void NewConnection(string connectionId); + void NewStream(string streamId); + void ConnectionError(string connectionId, Exception ex); + void StreamError(string streamId, Exception ex); + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicApi.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicApi.cs new file mode 100644 index 0000000000..ae17ff5eb2 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicApi.cs @@ -0,0 +1,251 @@ +// 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.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class MsQuicApi : IDisposable + { + private bool _disposed = false; + + private IntPtr _registrationContext; + + internal unsafe MsQuicApi() + { + var status = (uint)MsQuicNativeMethods.MsQuicOpen(version: 1, out var registration); + MsQuicStatusException.ThrowIfFailed(status); + + NativeRegistration = *registration; + + RegistrationOpenDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.RegistrationOpenDelegate>( + NativeRegistration.RegistrationOpen); + RegistrationCloseDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.RegistrationCloseDelegate>( + NativeRegistration.RegistrationClose); + + SecConfigCreateDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SecConfigCreateDelegate>( + NativeRegistration.SecConfigCreate); + SecConfigDeleteDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SecConfigDeleteDelegate>( + NativeRegistration.SecConfigDelete); + + SessionOpenDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SessionOpenDelegate>( + NativeRegistration.SessionOpen); + SessionCloseDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SessionCloseDelegate>( + NativeRegistration.SessionClose); + SessionShutdownDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SessionShutdownDelegate>( + NativeRegistration.SessionShutdown); + + ListenerOpenDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ListenerOpenDelegate>( + NativeRegistration.ListenerOpen); + ListenerCloseDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ListenerCloseDelegate>( + NativeRegistration.ListenerClose); + ListenerStartDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ListenerStartDelegate>( + NativeRegistration.ListenerStart); + ListenerStopDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ListenerStopDelegate>( + NativeRegistration.ListenerStop); + + ConnectionOpenDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ConnectionOpenDelegate>( + NativeRegistration.ConnectionOpen); + ConnectionCloseDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ConnectionCloseDelegate>( + NativeRegistration.ConnectionClose); + ConnectionShutdownDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ConnectionShutdownDelegate>( + NativeRegistration.ConnectionShutdown); + ConnectionStartDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.ConnectionStartDelegate>( + NativeRegistration.ConnectionStart); + + StreamOpenDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.StreamOpenDelegate>( + NativeRegistration.StreamOpen); + StreamCloseDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.StreamCloseDelegate>( + NativeRegistration.StreamClose); + StreamStartDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.StreamStartDelegate>( + NativeRegistration.StreamStart); + StreamShutdownDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.StreamShutdownDelegate>( + NativeRegistration.StreamShutdown); + StreamSendDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.StreamSendDelegate>( + NativeRegistration.StreamSend); + + SetContextDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SetContextDelegate>( + NativeRegistration.SetContext); + GetContextDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.GetContextDelegate>( + NativeRegistration.GetContext); + SetCallbackHandlerDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SetCallbackHandlerDelegate>( + NativeRegistration.SetCallbackHandler); + + SetParamDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.SetParamDelegate>( + NativeRegistration.SetParam); + GetParamDelegate = + Marshal.GetDelegateForFunctionPointer<MsQuicNativeMethods.GetParamDelegate>( + NativeRegistration.GetParam); + } + + internal MsQuicNativeMethods.NativeApi NativeRegistration { get; private set; } + + internal MsQuicNativeMethods.RegistrationOpenDelegate RegistrationOpenDelegate { get; private set; } + internal MsQuicNativeMethods.RegistrationCloseDelegate RegistrationCloseDelegate { get; private set; } + + internal MsQuicNativeMethods.SecConfigCreateDelegate SecConfigCreateDelegate { get; private set; } + internal MsQuicNativeMethods.SecConfigCreateCompleteDelegate SecConfigCreateCompleteDelegate { get; private set; } + internal MsQuicNativeMethods.SecConfigDeleteDelegate SecConfigDeleteDelegate { get; private set; } + + internal MsQuicNativeMethods.SessionOpenDelegate SessionOpenDelegate { get; private set; } + internal MsQuicNativeMethods.SessionCloseDelegate SessionCloseDelegate { get; private set; } + internal MsQuicNativeMethods.SessionShutdownDelegate SessionShutdownDelegate { get; private set; } + + internal MsQuicNativeMethods.ListenerOpenDelegate ListenerOpenDelegate { get; private set; } + internal MsQuicNativeMethods.ListenerCloseDelegate ListenerCloseDelegate { get; private set; } + internal MsQuicNativeMethods.ListenerStartDelegate ListenerStartDelegate { get; private set; } + internal MsQuicNativeMethods.ListenerStopDelegate ListenerStopDelegate { get; private set; } + + internal MsQuicNativeMethods.ConnectionOpenDelegate ConnectionOpenDelegate { get; private set; } + internal MsQuicNativeMethods.ConnectionCloseDelegate ConnectionCloseDelegate { get; private set; } + internal MsQuicNativeMethods.ConnectionShutdownDelegate ConnectionShutdownDelegate { get; private set; } + internal MsQuicNativeMethods.ConnectionStartDelegate ConnectionStartDelegate { get; private set; } + + internal MsQuicNativeMethods.StreamOpenDelegate StreamOpenDelegate { get; private set; } + internal MsQuicNativeMethods.StreamCloseDelegate StreamCloseDelegate { get; private set; } + internal MsQuicNativeMethods.StreamStartDelegate StreamStartDelegate { get; private set; } + internal MsQuicNativeMethods.StreamShutdownDelegate StreamShutdownDelegate { get; private set; } + internal MsQuicNativeMethods.StreamSendDelegate StreamSendDelegate { get; private set; } + internal MsQuicNativeMethods.StreamReceiveCompleteDelegate StreamReceiveComplete { get; private set; } + + internal MsQuicNativeMethods.SetContextDelegate SetContextDelegate { get; private set; } + internal MsQuicNativeMethods.GetContextDelegate GetContextDelegate { get; private set; } + internal MsQuicNativeMethods.SetCallbackHandlerDelegate SetCallbackHandlerDelegate { get; private set; } + + internal MsQuicNativeMethods.SetParamDelegate SetParamDelegate { get; private set; } + internal MsQuicNativeMethods.GetParamDelegate GetParamDelegate { get; private set; } + + internal void RegistrationOpen(byte[] name) + { + MsQuicStatusException.ThrowIfFailed(RegistrationOpenDelegate(name, out var ctx)); + _registrationContext = ctx; + } + + internal unsafe uint UnsafeSetParam( + IntPtr Handle, + uint Level, + uint Param, + MsQuicNativeMethods.QuicBuffer Buffer) + { + return SetParamDelegate( + Handle, + Level, + Param, + Buffer.Length, + Buffer.Buffer); + } + + internal unsafe uint UnsafeGetParam( + IntPtr Handle, + uint Level, + uint Param, + ref MsQuicNativeMethods.QuicBuffer Buffer) + { + return GetParamDelegate( + Handle, + Level, + Param, + out Buffer.Length, + out Buffer.Buffer); + } + + public async ValueTask<QuicSecConfig> CreateSecurityConfig(X509Certificate2 certificate) + { + QuicSecConfig secConfig = null; + var tcs = new TaskCompletionSource<object>(); + var secConfigCreateStatus = MsQuicConstants.InternalError; + + var status = SecConfigCreateDelegate( + _registrationContext, + (uint)QUIC_SEC_CONFIG_FLAG.CERT_CONTEXT, + certificate.Handle, + null, + IntPtr.Zero, + SecCfgCreateCallbackHandler); + + MsQuicStatusException.ThrowIfFailed(status); + + void SecCfgCreateCallbackHandler( + IntPtr context, + uint status, + IntPtr securityConfig) + { + secConfig = new QuicSecConfig(this, securityConfig); + secConfigCreateStatus = status; + tcs.SetResult(null); + } + + await tcs.Task; + + MsQuicStatusException.ThrowIfFailed(secConfigCreateStatus); + + return secConfig; + } + + public QuicSession SessionOpen( + string alpn) + { + var sessionPtr = IntPtr.Zero; + + var status = SessionOpenDelegate( + _registrationContext, + Encoding.UTF8.GetBytes(alpn), + IntPtr.Zero, + ref sessionPtr); + MsQuicStatusException.ThrowIfFailed(status); + + return new QuicSession(this, sessionPtr); + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + ~MsQuicApi() + { + Dispose(disposing: false); + } + + private void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + RegistrationCloseDelegate?.Invoke(_registrationContext); + + _disposed = true; + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConnection.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConnection.cs new file mode 100644 index 0000000000..b1b10ae1dd --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConnection.cs @@ -0,0 +1,336 @@ +// 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.Runtime.InteropServices; +using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Abstractions.Features; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.AspNetCore.Http.Features; +using static Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal.MsQuicNativeMethods; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class MsQuicConnection : TransportConnection, IQuicStreamListenerFeature, IQuicCreateStreamFeature, IDisposable + { + public MsQuicApi _api; + private bool _disposed; + private readonly MsQuicTransportContext _context; + private readonly IMsQuicTrace _log; + private IntPtr _nativeObjPtr; + private static GCHandle _handle; + private ConnectionCallbackDelegate _connectionDelegate; + private readonly Channel<MsQuicStream> _acceptQueue = Channel.CreateUnbounded<MsQuicStream>(new UnboundedChannelOptions + { + SingleReader = true, + SingleWriter = true + }); + + public MsQuicConnection(MsQuicApi api, MsQuicTransportContext context, IntPtr nativeObjPtr) + { + _api = api; + _context = context; + _log = context.Log; + _nativeObjPtr = nativeObjPtr; + + SetCallbackHandler(); + + SetIdleTimeout(_context.Options.IdleTimeout); + + Features.Set<ITlsConnectionFeature>(new FakeTlsConnectionFeature()); + Features.Set<IQuicStreamListenerFeature>(this); + Features.Set<IQuicCreateStreamFeature>(this); + + _log.NewConnection(ConnectionId); + } + + internal uint HandleEvent(ref ConnectionEvent connectionEvent) + { + var status = MsQuicConstants.Success; + switch (connectionEvent.Type) + { + case QUIC_CONNECTION_EVENT.CONNECTED: + { + status = HandleEventConnected( + connectionEvent); + } + break; + + case QUIC_CONNECTION_EVENT.SHUTDOWN_BEGIN: + { + status = HandleEventShutdownBegin( + connectionEvent); + } + break; + + case QUIC_CONNECTION_EVENT.SHUTDOWN_BEGIN_PEER: + { + status = HandleEventShutdownBeginPeer( + connectionEvent); + } + break; + + case QUIC_CONNECTION_EVENT.SHUTDOWN_COMPLETE: + { + status = HandleEventShutdownComplete( + connectionEvent); + } + break; + + case QUIC_CONNECTION_EVENT.NEW_STREAM: + { + status = HandleEventNewStream( + connectionEvent); + } + break; + + case QUIC_CONNECTION_EVENT.STREAMS_AVAILABLE: + { + status = HandleEventStreamsAvailable( + connectionEvent); + } + break; + + default: + break; + } + return status; + } + + protected virtual uint HandleEventConnected(ConnectionEvent connectionEvent) + { + return MsQuicConstants.Success; + } + + protected virtual uint HandleEventShutdownBegin(ConnectionEvent connectionEvent) + { + return MsQuicConstants.Success; + } + + protected virtual uint HandleEventShutdownBeginPeer(ConnectionEvent connectionEvent) + { + return MsQuicConstants.Success; + } + + protected virtual uint HandleEventShutdownComplete(ConnectionEvent connectionEvent) + { + return MsQuicConstants.Success; + } + + protected virtual uint HandleEventNewStream(ConnectionEvent connectionEvent) + { + var msQuicStream = new MsQuicStream(_api, this, _context, connectionEvent.StreamFlags, connectionEvent.Data.NewStream.Stream); + + _acceptQueue.Writer.TryWrite(msQuicStream); + + return MsQuicConstants.Success; + } + + protected virtual uint HandleEventStreamsAvailable(ConnectionEvent connectionEvent) + { + return MsQuicConstants.Success; + } + + public async ValueTask<ConnectionContext> AcceptAsync() + { + if (await _acceptQueue.Reader.WaitToReadAsync()) + { + if (_acceptQueue.Reader.TryRead(out var stream)) + { + return stream; + } + } + + return null; + } + + public ValueTask<ConnectionContext> StartUnidirectionalStreamAsync() + { + return StartStreamAsync(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL); + } + + public ValueTask<ConnectionContext> StartBidirectionalStreamAsync() + { + return StartStreamAsync(QUIC_STREAM_OPEN_FLAG.NONE); + } + + private async ValueTask<ConnectionContext> StartStreamAsync(QUIC_STREAM_OPEN_FLAG flags) + { + var stream = StreamOpen(flags); + await stream.StartAsync(); + return stream; + } + + public unsafe void SetIdleTimeout(TimeSpan timeout) + { + var msTime = (ulong)timeout.TotalMilliseconds; + var buffer = new QuicBuffer() + { + Length = sizeof(ulong), + Buffer = (byte*)&msTime + }; + SetParam(QUIC_PARAM_CONN.IDLE_TIMEOUT, buffer); + } + + public void SetPeerBiDirectionalStreamCount(ushort count) + { + SetUshortParamter(QUIC_PARAM_CONN.PEER_BIDI_STREAM_COUNT, count); + } + + public void SetPeerUnidirectionalStreamCount(ushort count) + { + SetUshortParamter(QUIC_PARAM_CONN.PEER_UNIDI_STREAM_COUNT, count); + } + + public void SetLocalBidirectionalStreamCount(ushort count) + { + SetUshortParamter(QUIC_PARAM_CONN.LOCAL_BIDI_STREAM_COUNT, count); + } + + public void SetLocalUnidirectionalStreamCount(ushort count) + { + SetUshortParamter(QUIC_PARAM_CONN.LOCAL_UNIDI_STREAM_COUNT, count); + } + + public unsafe void EnableBuffering() + { + var val = true; + var buffer = new QuicBuffer() + { + Length = sizeof(bool), + Buffer = (byte*)&val + }; + SetParam(QUIC_PARAM_CONN.USE_SEND_BUFFER, buffer); + } + + public unsafe void DisableBuffering() + { + var val = false; + var buffer = new QuicBuffer() + { + Length = sizeof(bool), + Buffer = (byte*)&val + }; + SetParam(QUIC_PARAM_CONN.USE_SEND_BUFFER, buffer); + } + + public ValueTask StartAsync( + ushort family, + string serverName, + ushort serverPort) + { + var status = _api.ConnectionStartDelegate( + _nativeObjPtr, + family, + serverName, + serverPort); + + MsQuicStatusException.ThrowIfFailed(status); + + return new ValueTask(); + } + + public MsQuicStream StreamOpen( + QUIC_STREAM_OPEN_FLAG flags) + { + var streamPtr = IntPtr.Zero; + var status = _api.StreamOpenDelegate( + _nativeObjPtr, + (uint)flags, + MsQuicStream.NativeCallbackHandler, + IntPtr.Zero, + out streamPtr); + MsQuicStatusException.ThrowIfFailed(status); + + return new MsQuicStream(_api, this, _context, flags, streamPtr); + } + + public void SetCallbackHandler() + { + _handle = GCHandle.Alloc(this); + _connectionDelegate = new ConnectionCallbackDelegate(NativeCallbackHandler); + _api.SetCallbackHandlerDelegate( + _nativeObjPtr, + _connectionDelegate, + GCHandle.ToIntPtr(_handle)); + } + + public void Shutdown( + QUIC_CONNECTION_SHUTDOWN_FLAG Flags, + ushort ErrorCode) + { + var status = _api.ConnectionShutdownDelegate( + _nativeObjPtr, + (uint)Flags, + ErrorCode); + MsQuicStatusException.ThrowIfFailed(status); + } + + internal static uint NativeCallbackHandler( + IntPtr connection, + IntPtr context, + ref ConnectionEvent connectionEventStruct) + { + var handle = GCHandle.FromIntPtr(context); + var quicConnection = (MsQuicConnection)handle.Target; + return quicConnection.HandleEvent(ref connectionEventStruct); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~MsQuicConnection() + { + Dispose(false); + } + + private void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + if (_nativeObjPtr != IntPtr.Zero) + { + _api.ConnectionCloseDelegate?.Invoke(_nativeObjPtr); + } + + _nativeObjPtr = IntPtr.Zero; + _api = null; + + _handle.Free(); + _disposed = true; + } + + private unsafe void SetUshortParamter(QUIC_PARAM_CONN param, ushort count) + { + var buffer = new QuicBuffer() + { + Length = sizeof(ushort), + Buffer = (byte*)&count + }; + SetParam(param, buffer); + } + + private void SetParam( + QUIC_PARAM_CONN param, + QuicBuffer buf) + { + MsQuicStatusException.ThrowIfFailed(_api.UnsafeSetParam( + _nativeObjPtr, + (uint)QUIC_PARAM_LEVEL.CONNECTION, + (uint)param, + buf)); + } + + public override void Abort(ConnectionAbortedException abortReason) + { + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConnectionListener.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConnectionListener.cs new file mode 100644 index 0000000000..27e2dd5912 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConnectionListener.cs @@ -0,0 +1,197 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using static Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal.MsQuicNativeMethods; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + /// <summary> + /// Listens for new Quic Connections. + /// </summary> + internal class MsQuicConnectionListener : IConnectionListener, IAsyncDisposable, IDisposable + { + private IMsQuicTrace _log; + private MsQuicApi _api; + private QuicSecConfig _secConfig; + private QuicSession _session; + private bool _disposed; + private bool _stopped; + private IntPtr _nativeObjPtr; + private GCHandle _handle; + private ListenerCallbackDelegate _listenerDelegate; + private MsQuicTransportContext _transportContext; + + private readonly Channel<MsQuicConnection> _acceptConnectionQueue = Channel.CreateUnbounded<MsQuicConnection>(new UnboundedChannelOptions + { + SingleReader = true, + SingleWriter = true + }); + + public MsQuicConnectionListener(MsQuicTransportOptions options, IHostApplicationLifetime lifetime, IMsQuicTrace log, EndPoint endpoint) + { + _api = new MsQuicApi(); + _log = log; + _transportContext = new MsQuicTransportContext(lifetime, _log, options); + EndPoint = endpoint; + } + + public EndPoint EndPoint { get; set; } + + public async ValueTask<ConnectionContext> AcceptAsync(CancellationToken cancellationToken = default) + { + if (await _acceptConnectionQueue.Reader.WaitToReadAsync()) + { + if (_acceptConnectionQueue.Reader.TryRead(out var connection)) + { + return connection; + } + } + + return null; + } + + internal async Task BindAsync() + { + await StartAsync(); + } + + public async ValueTask UnbindAsync(CancellationToken cancellationToken = default) + { + if (_stopped) + { + return; + } + + // TODO abort all streams and connections here? + _stopped = true; + + await DisposeAsync(); + } + + public async Task StartAsync(CancellationToken cancellationToken = default) + { + _api.RegistrationOpen(Encoding.ASCII.GetBytes(_transportContext.Options.RegistrationName)); + + _secConfig = await _api.CreateSecurityConfig(_transportContext.Options.Certificate); + + _session = _api.SessionOpen(_transportContext.Options.Alpn); + _log.LogDebug(0, "Started session"); + + _nativeObjPtr = _session.ListenerOpen(NativeCallbackHandler); + + SetCallbackHandler(); + + _session.SetIdleTimeout(_transportContext.Options.IdleTimeout); + _session.SetPeerBiDirectionalStreamCount(_transportContext.Options.MaxBidirectionalStreamCount); + _session.SetPeerUnidirectionalStreamCount(_transportContext.Options.MaxBidirectionalStreamCount); + + var address = MsQuicNativeMethods.Convert(EndPoint as IPEndPoint); + + MsQuicStatusException.ThrowIfFailed(_api.ListenerStartDelegate( + _nativeObjPtr, + ref address)); + } + + internal uint ListenerCallbackHandler( + ref ListenerEvent evt) + { + switch (evt.Type) + { + case QUIC_LISTENER_EVENT.NEW_CONNECTION: + { + + evt.Data.NewConnection.SecurityConfig = _secConfig.NativeObjPtr; + var msQuicConnection = new MsQuicConnection(_api, _transportContext, evt.Data.NewConnection.Connection); + _acceptConnectionQueue.Writer.TryWrite(msQuicConnection); + } + break; + default: + return MsQuicConstants.InternalError; + } + + return MsQuicConstants.Success; + } + + protected void StopAcceptingConnections() + { + _acceptConnectionQueue.Writer.TryComplete(); + } + + internal static uint NativeCallbackHandler( + IntPtr listener, + IntPtr context, + ref ListenerEvent connectionEventStruct) + { + var handle = GCHandle.FromIntPtr(context); + var quicListener = (MsQuicConnectionListener)handle.Target; + + return quicListener.ListenerCallbackHandler(ref connectionEventStruct); + } + + internal void SetCallbackHandler() + { + _handle = GCHandle.Alloc(this); + _listenerDelegate = new ListenerCallbackDelegate(NativeCallbackHandler); + _api.SetCallbackHandlerDelegate( + _nativeObjPtr, + _listenerDelegate, + GCHandle.ToIntPtr(_handle)); + } + + ~MsQuicConnectionListener() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public ValueTask DisposeAsync() + { + if (_disposed) + { + return new ValueTask(); + } + + Dispose(true); + + return new ValueTask(); + } + + private void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + StopAcceptingConnections(); + + if (_nativeObjPtr != IntPtr.Zero) + { + _api.ListenerStopDelegate(_nativeObjPtr); + _api.ListenerCloseDelegate(_nativeObjPtr); + } + + _nativeObjPtr = IntPtr.Zero; + _api = null; + _disposed = true; + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConstants.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConstants.cs new file mode 100644 index 0000000000..69071d60a9 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicConstants.cs @@ -0,0 +1,151 @@ +// 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.Runtime.InteropServices; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal static class MsQuicConstants + { + internal static uint InternalError = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Windows.InternalError : Linux.InternalError; + internal static uint Success = 0; + internal static uint Pending = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Windows.Pending : Linux.Pending; + private const uint SuccessConst = 0; + + internal static Func<uint, string> ErrorTypeFromErrorCode = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Windows.GetError : (Func<uint, string>)Linux.GetError; + + internal static class Windows + { + internal const uint Pending = 0x703E5; + internal const uint Continue = 0x704DE; + internal const uint OutOfMemory = 0x8007000E; + internal const uint InvalidParameter = 0x80070057; + internal const uint InvalidState = 0x8007139F; + internal const uint NotSupported = 0x80004002; + internal const uint NotFound = 0x80070490; + internal const uint BufferTooSmall = 0x8007007A; + internal const uint HandshakeFailure = 0x80410000; + internal const uint Aborted = 0x80004004; + internal const uint AddressInUse = 0x80072740; + internal const uint ConnectionTimeout = 0x800704CF; + internal const uint ConnectionIdle = 0x800704D4; + internal const uint InternalError = 0x80004005; + internal const uint ServerBusy = 0x800704C9; + internal const uint ProtocolError = 0x800704CD; + internal const uint VerNegError = 0x80410001; + + // TODO return better error messages here. + public static string GetError(uint status) + { + switch (status) + { + case SuccessConst: + return "SUCCESS"; + case Pending: + return "PENDING"; + case Continue: + return "CONTINUE"; + case OutOfMemory: + return "OUT_OF_MEMORY"; + case InvalidParameter: + return "INVALID_PARAMETER"; + case InvalidState: + return "INVALID_STATE"; + case NotSupported: + return "NOT_SUPPORTED"; + case NotFound: + return "NOT_FOUND"; + case BufferTooSmall: + return "BUFFER_TOO_SMALL"; + case HandshakeFailure: + return "HANDSHAKE_FAILURE"; + case Aborted: + return "ABORTED"; + case AddressInUse: + return "ADDRESS_IN_USE"; + case ConnectionTimeout: + return "CONNECTION_TIMEOUT"; + case ConnectionIdle: + return "CONNECTION_IDLE"; + case InternalError: + return "INTERNAL_ERROR"; + case ServerBusy: + return "SERVER_BUSY"; + case ProtocolError: + return "PROTOCOL_ERROR"; + case VerNegError: + return "VER_NEG_ERROR"; + } + return status.ToString(); + } + } + + internal static class Linux + { + internal const uint Pending = unchecked((uint)-2); + internal const uint Continue = unchecked((uint)-1); + internal const uint OutOfMemory = 12; + internal const uint InvalidParameter = 22; + internal const uint InvalidState = 200000002; + internal const uint NotSupported = 95; + internal const uint NotFound = 2; + internal const uint BufferTooSmall = 75; + internal const uint HandshakeFailure = 200000009; + internal const uint Aborted = 200000008; + internal const uint AddressInUse = 98; + internal const uint ConnectionTimeout = 110; + internal const uint ConnectionIdle = 200000011; + internal const uint InternalError = 200000012; + internal const uint ServerBusy = 200000007; + internal const uint ProtocolError = 200000013; + internal const uint VerNegError = 200000014; + + + public static string GetError(uint status) + { + switch (status) + { + case SuccessConst: + return "SUCCESS"; + case Pending: + return "PENDING"; + case Continue: + return "CONTINUE"; + case OutOfMemory: + return "OUT_OF_MEMORY"; + case InvalidParameter: + return "INVALID_PARAMETER"; + case InvalidState: + return "INVALID_STATE"; + case NotSupported: + return "NOT_SUPPORTED"; + case NotFound: + return "NOT_FOUND"; + case BufferTooSmall: + return "BUFFER_TOO_SMALL"; + case HandshakeFailure: + return "HANDSHAKE_FAILURE"; + case Aborted: + return "ABORTED"; + case AddressInUse: + return "ADDRESS_IN_USE"; + case ConnectionTimeout: + return "CONNECTION_TIMEOUT"; + case ConnectionIdle: + return "CONNECTION_IDLE"; + case InternalError: + return "INTERNAL_ERROR"; + case ServerBusy: + return "SERVER_BUSY"; + case ProtocolError: + return "PROTOCOL_ERROR"; + case VerNegError: + return "VER_NEG_ERROR"; + } + + return status.ToString(); + } + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicEnums.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicEnums.cs new file mode 100644 index 0000000000..37174ba4ec --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicEnums.cs @@ -0,0 +1,178 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + /// <summary> + /// Flags to pass when creating a certificate hash store. + /// </summary> + [Flags] + internal enum QUIC_CERT_HASH_STORE_FLAG : uint + { + NONE = 0, + MACHINE_CERT = 0x0001, + } + + /// <summary> + /// Flags to pass when creating a security config. + /// </summary> + [Flags] + internal enum QUIC_SEC_CONFIG_FLAG : uint + { + NONE = 0, + CERT_HASH = 0x00000001, + CERT_HASH_STORE = 0x00000002, + CERT_CONTEXT = 0x00000004, + CERT_FILE = 0x00000008, + ENABL_OCSP = 0x00000010, + CERT_NULL = 0xF0000000, + } + + internal enum QUIC_LISTENER_EVENT : byte + { + NEW_CONNECTION = 0 + } + + internal enum QUIC_CONNECTION_EVENT : byte + { + CONNECTED = 0, + SHUTDOWN_BEGIN = 1, + SHUTDOWN_BEGIN_PEER = 2, + SHUTDOWN_COMPLETE = 3, + LOCAL_ADDR_CHANGED = 4, + PEER_ADDR_CHANGED = 5, + NEW_STREAM = 6, + STREAMS_AVAILABLE = 7, + PEER_NEEDS_STREAMS = 8, + IDEAL_SEND_BUFFER = 9, + } + + [Flags] + internal enum QUIC_CONNECTION_SHUTDOWN_FLAG : uint + { + NONE = 0x0, + SILENT = 0x1 + } + + internal enum QUIC_PARAM_LEVEL : uint + { + REGISTRATION = 0, + SESSION = 1, + LISTENER = 2, + CONNECTION = 3, + TLS = 4, + STREAM = 5, + } + + internal enum QUIC_PARAM_REGISTRATION : uint + { + RETRY_MEMORY_PERCENT = 0, + CID_PREFIX = 1 + } + + internal enum QUIC_PARAM_SESSION : uint + { + TLS_TICKET_KEY = 0, + PEER_BIDI_STREAM_COUNT = 1, + PEER_UNIDI_STREAM_COUNT = 2, + IDLE_TIMEOUT = 3, + DISCONNECT_TIMEOUT = 4, + MAX_BYTES_PER_KEY = 5 + } + + internal enum QUIC_PARAM_LISTENER : uint + { + LOCAL_ADDRESS = 0 + } + + internal enum QUIC_PARAM_CONN : uint + { + QUIC_VERSION = 0, + LOCAL_ADDRESS = 1, + REMOTE_ADDRESS = 2, + IDLE_TIMEOUT = 3, + PEER_BIDI_STREAM_COUNT = 4, + PEER_UNIDI_STREAM_COUNT = 5, + LOCAL_BIDI_STREAM_COUNT = 6, + LOCAL_UNIDI_STREAM_COUNT = 7, + CLOSE_REASON_PHRASE = 8, + STATISTICS = 9, + STATISTICS_PLAT = 10, + CERT_VALIDATION_FLAGS = 11, + KEEP_ALIVE_ENABLED = 12, + DISCONNECT_TIMEOUT = 13, + SEC_CONFIG = 14, + USE_SEND_BUFFER = 15, + USE_PACING = 16, + SHARE_UDP_BINDING = 17, + IDEAL_PROCESSOR = 18, + MAX_STREAM_IDS = 19 + } + + internal enum QUIC_PARAM_STREAM : uint + { + ID = 0, + RECEIVE_ENABLED = 1, + ZERORTT_LENGTH = 2, + IDEAL_SEND_BUFFER = 3 + } + + internal enum QUIC_STREAM_EVENT : byte + { + START_COMPLETE = 0, + RECV = 1, + SEND_COMPLETE = 2, + PEER_SEND_CLOSE = 3, + PEER_SEND_ABORT = 4, + PEER_RECV_ABORT = 5, + SEND_SHUTDOWN_COMPLETE = 6, + SHUTDOWN_COMPLETE = 7, + IDEAL_SEND_BUFFER_SIZE = 8, + } + + [Flags] + internal enum QUIC_STREAM_OPEN_FLAG : uint + { + NONE = 0, + UNIDIRECTIONAL = 0x1, + ZERO_RTT = 0x2, + } + + [Flags] + internal enum QUIC_STREAM_START_FLAG : uint + { + NONE = 0, + FAIL_BLOCKED = 0x1, + IMMEDIATE = 0x2, + ASYNC = 0x4, + } + + [Flags] + internal enum QUIC_STREAM_SHUTDOWN_FLAG : uint + { + NONE = 0, + GRACEFUL = 0x1, + ABORT_SEND = 0x2, + ABORT_RECV = 0x4, + ABORT = 0x6, + IMMEDIATE = 0x8 + } + + [Flags] + internal enum QUIC_SEND_FLAG : uint + { + NONE = 0, + ALLOW_0_RTT = 0x00000001, + FIN = 0x00000002, + } + + [Flags] + internal enum QUIC_RECV_FLAG : byte + { + NONE = 0, + ZERO_RTT = 0x1, + FIN = 0x02 + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicNativeMethods.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicNativeMethods.cs new file mode 100644 index 0000000000..d5512c5687 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicNativeMethods.cs @@ -0,0 +1,590 @@ +// 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.Net; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Text; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + /// <summary> + /// Contains all native delegates and structs that are used with MsQuic. + /// </summary> + internal unsafe static class MsQuicNativeMethods + { + internal const string dllName = "msquic"; + + [DllImport(dllName)] + internal static extern int MsQuicOpen(int version, out NativeApi* registration); + + [StructLayout(LayoutKind.Sequential)] + internal struct NativeApi + { + internal uint Version; + + internal IntPtr SetContext; + internal IntPtr GetContext; + internal IntPtr SetCallbackHandler; + + internal IntPtr SetParam; + internal IntPtr GetParam; + + internal IntPtr RegistrationOpen; + internal IntPtr RegistrationClose; + + internal IntPtr SecConfigCreate; + internal IntPtr SecConfigDelete; + + internal IntPtr SessionOpen; + internal IntPtr SessionClose; + internal IntPtr SessionShutdown; + + internal IntPtr ListenerOpen; + internal IntPtr ListenerClose; + internal IntPtr ListenerStart; + internal IntPtr ListenerStop; + + internal IntPtr ConnectionOpen; + internal IntPtr ConnectionClose; + internal IntPtr ConnectionShutdown; + internal IntPtr ConnectionStart; + + internal IntPtr StreamOpen; + internal IntPtr StreamClose; + internal IntPtr StreamStart; + internal IntPtr StreamShutdown; + internal IntPtr StreamSend; + internal IntPtr StreamReceiveComplete; + } + + internal delegate uint SetContextDelegate( + IntPtr Handle, + IntPtr Context); + + internal delegate IntPtr GetContextDelegate( + IntPtr Handle); + + internal delegate void SetCallbackHandlerDelegate( + IntPtr Handle, + Delegate del, + IntPtr Context); + + internal delegate uint SetParamDelegate( + IntPtr Handle, + uint Level, + uint Param, + uint BufferLength, + byte* Buffer); + + internal delegate uint GetParamDelegate( + IntPtr Handle, + uint Level, + uint Param, + out uint BufferLength, + out byte* Buffer); + + internal delegate uint RegistrationOpenDelegate(byte[] appName, out IntPtr RegistrationContext); + + internal delegate void RegistrationCloseDelegate(IntPtr RegistrationContext); + + [StructLayout(LayoutKind.Sequential)] + internal struct CertHash + { + internal const int ShaHashLength = 20; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ShaHashLength)] + internal byte[] ShaHash; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct CertHashStore + { + internal const int ShaHashLength = 20; + internal const int StoreNameLength = 128; + + internal uint Flags; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ShaHashLength)] + internal byte[] ShaHash; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = StoreNameLength)] + internal byte[] StoreName; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct CertFile + { + [MarshalAs(UnmanagedType.ByValArray)] + internal byte[] ShaHashUtf8; + [MarshalAs(UnmanagedType.ByValArray)] + internal byte[] StoreNameUtf8; + } + + internal delegate void SecConfigCreateCompleteDelegate(IntPtr Context, uint Status, IntPtr SecurityConfig); + + internal delegate uint SecConfigCreateDelegate( + IntPtr RegistrationContext, + uint Flags, + IntPtr Certificate, + [MarshalAs(UnmanagedType.LPStr)]string Principal, + IntPtr Context, + SecConfigCreateCompleteDelegate CompletionHandler); + + internal delegate void SecConfigDeleteDelegate( + IntPtr SecurityConfig); + + internal delegate uint SessionOpenDelegate( + IntPtr RegistrationContext, + byte[] utf8String, + IntPtr Context, + ref IntPtr Session); + + internal delegate void SessionCloseDelegate( + IntPtr Session); + + internal delegate void SessionShutdownDelegate( + IntPtr Session, + uint Flags, + ushort ErrorCode); + + [StructLayout(LayoutKind.Sequential)] + internal struct ListenerEvent + { + internal QUIC_LISTENER_EVENT Type; + internal ListenerEventDataUnion Data; + } + + [StructLayout(LayoutKind.Explicit)] + internal struct ListenerEventDataUnion + { + [FieldOffset(0)] + internal ListenerEventDataNewConnection NewConnection; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ListenerEventDataNewConnection + { + internal IntPtr Info; + internal IntPtr Connection; + internal IntPtr SecurityConfig; + + internal static string BufferToString(IntPtr buffer, ushort bufferLength) + { + if (bufferLength == 0) + { + return ""; + } + + var utf8Bytes = new byte[bufferLength]; // TODO: Avoid extra alloc and copy. + Marshal.Copy(buffer, utf8Bytes, 0, bufferLength); + var str = Encoding.UTF8.GetString(utf8Bytes); + return str; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct NewConnectionInfo + { + internal uint QuicVersion; + internal IntPtr LocalAddress; + internal IntPtr RemoteAddress; + internal ushort CryptoBufferLength; + internal ushort AlpnListLength; + internal ushort ServerNameLength; + internal IntPtr CryptoBuffer; + internal IntPtr AlpnList; + internal IntPtr ServerName; + } + + internal delegate uint ListenerCallbackDelegate( + IntPtr listener, + IntPtr context, + ref ListenerEvent evt); + + internal delegate uint ListenerOpenDelegate( + IntPtr session, + ListenerCallbackDelegate handler, + IntPtr context, + out IntPtr listener); + + internal delegate uint ListenerCloseDelegate( + IntPtr listener); + + internal delegate uint ListenerStartDelegate( + IntPtr listener, + ref SOCKADDR_INET localAddress); + + internal delegate uint ListenerStopDelegate( + IntPtr listener); + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataConnected + { + internal bool EarlyDataAccepted; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataShutdownBegin + { + internal uint Status; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataShutdownBeginPeer + { + internal ushort ErrorCode; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataShutdownComplete + { + internal bool TimedOut; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataLocalAddrChanged + { + internal IntPtr Address; // TODO this needs to be IPV4 and IPV6 + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataPeerAddrChanged + { + internal IntPtr Address; // TODO this needs to be IPV4 and IPV6 + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataNewStream + { + internal IntPtr Stream; + internal QUIC_STREAM_OPEN_FLAG Flags; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataStreamsAvailable + { + internal ushort BiDirectionalCount; + internal ushort UniDirectionalCount; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEventDataIdealSendBuffer + { + internal ulong NumBytes; + } + + [StructLayout(LayoutKind.Explicit)] + internal struct ConnectionEventDataUnion + { + [FieldOffset(0)] + internal ConnectionEventDataConnected Connected; + + [FieldOffset(0)] + internal ConnectionEventDataShutdownBegin ShutdownBegin; + + [FieldOffset(0)] + internal ConnectionEventDataShutdownBeginPeer ShutdownBeginPeer; + + [FieldOffset(0)] + internal ConnectionEventDataShutdownComplete ShutdownComplete; + + [FieldOffset(0)] + internal ConnectionEventDataLocalAddrChanged LocalAddrChanged; + + [FieldOffset(0)] + internal ConnectionEventDataPeerAddrChanged PeerAddrChanged; + + [FieldOffset(0)] + internal ConnectionEventDataNewStream NewStream; + + [FieldOffset(0)] + internal ConnectionEventDataStreamsAvailable StreamsAvailable; + + [FieldOffset(0)] + internal ConnectionEventDataIdealSendBuffer IdealSendBuffer; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ConnectionEvent + { + internal QUIC_CONNECTION_EVENT Type; + internal ConnectionEventDataUnion Data; + + internal bool EarlyDataAccepted => Data.Connected.EarlyDataAccepted; + internal ulong NumBytes => Data.IdealSendBuffer.NumBytes; + internal IPEndPoint LocalAddress => null; // TODO + internal IPEndPoint PeerAddress => null; // TODO + internal uint ShutdownBeginStatus => Data.ShutdownBegin.Status; + internal ushort ShutdownBeginPeerStatus => Data.ShutdownBeginPeer.ErrorCode; + internal bool ShutdownTimedOut => Data.ShutdownComplete.TimedOut; + internal ushort BiDirectionalCount => Data.StreamsAvailable.BiDirectionalCount; + internal ushort UniDirectionalCount => Data.StreamsAvailable.UniDirectionalCount; + internal QUIC_STREAM_OPEN_FLAG StreamFlags => Data.NewStream.Flags; + } + + internal delegate uint ConnectionCallbackDelegate( + IntPtr Connection, + IntPtr Context, + ref ConnectionEvent Event); + + internal delegate uint ConnectionOpenDelegate( + IntPtr Session, + ConnectionCallbackDelegate Handler, + IntPtr Context, + out IntPtr Connection); + + internal delegate uint ConnectionCloseDelegate( + IntPtr Connection); + + internal delegate uint ConnectionStartDelegate( + IntPtr Connection, + ushort Family, + [MarshalAs(UnmanagedType.LPStr)] + string ServerName, + ushort ServerPort); + + internal delegate uint ConnectionShutdownDelegate( + IntPtr Connection, + uint Flags, + ushort ErrorCode); + + [StructLayout(LayoutKind.Sequential)] + internal struct StreamEventDataRecv + { + internal ulong AbsoluteOffset; + internal ulong TotalBufferLength; + internal QuicBuffer* Buffers; + internal uint BufferCount; + internal byte Flags; + } + + [StructLayout(LayoutKind.Explicit)] + internal struct StreamEventDataSendComplete + { + [FieldOffset(7)] + internal byte Canceled; + [FieldOffset(8)] + internal IntPtr ClientContext; + + internal bool IsCanceled() + { + return Canceled != 0; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct StreamEventDataPeerSendAbort + { + internal ushort ErrorCode; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct StreamEventDataPeerRecvAbort + { + internal ushort ErrorCode; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct StreamEventDataSendShutdownComplete + { + internal bool Graceful; + } + + [StructLayout(LayoutKind.Explicit)] + internal struct StreamEventDataUnion + { + [FieldOffset(0)] + internal StreamEventDataRecv Recv; + + [FieldOffset(0)] + internal StreamEventDataSendComplete SendComplete; + + [FieldOffset(0)] + internal StreamEventDataPeerSendAbort PeerSendAbort; + + [FieldOffset(0)] + internal StreamEventDataPeerRecvAbort PeerRecvAbort; + + [FieldOffset(0)] + internal StreamEventDataSendShutdownComplete SendShutdownComplete; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct StreamEvent + { + internal QUIC_STREAM_EVENT Type; + internal StreamEventDataUnion Data; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SOCKADDR_IN + { + internal ushort sin_family; + internal ushort sin_port; + internal byte sin_addr0; + internal byte sin_addr1; + internal byte sin_addr2; + internal byte sin_addr3; + + internal byte[] Address + { + get + { + return new byte[] { sin_addr0, sin_addr1, sin_addr2, sin_addr3 }; + } + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct SOCKADDR_IN6 + { + internal ushort sin6_family; + internal ushort sin6_port; + internal uint sin6_flowinfo; + internal byte sin6_addr0; + internal byte sin6_addr1; + internal byte sin6_addr2; + internal byte sin6_addr3; + internal byte sin6_addr4; + internal byte sin6_addr5; + internal byte sin6_addr6; + internal byte sin6_addr7; + internal byte sin6_addr8; + internal byte sin6_addr9; + internal byte sin6_addr10; + internal byte sin6_addr11; + internal byte sin6_addr12; + internal byte sin6_addr13; + internal byte sin6_addr14; + internal byte sin6_addr15; + internal uint sin6_scope_id; + + internal byte[] Address + { + get + { + return new byte[] { + sin6_addr0, sin6_addr1, sin6_addr2, sin6_addr3 , + sin6_addr4, sin6_addr5, sin6_addr6, sin6_addr7 , + sin6_addr8, sin6_addr9, sin6_addr10, sin6_addr11 , + sin6_addr12, sin6_addr13, sin6_addr14, sin6_addr15 }; + } + } + } + + [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)] + internal struct SOCKADDR_INET + { + [FieldOffset(0)] + internal SOCKADDR_IN Ipv4; + [FieldOffset(0)] + internal SOCKADDR_IN6 Ipv6; + [FieldOffset(0)] + internal ushort si_family; + } + + internal delegate uint StreamCallbackDelegate( + IntPtr Stream, + IntPtr Context, + StreamEvent Event); + + internal delegate uint StreamOpenDelegate( + IntPtr Connection, + uint Flags, + StreamCallbackDelegate Handler, + IntPtr Context, + out IntPtr Stream); + + internal delegate uint StreamStartDelegate( + IntPtr Stream, + uint Flags + ); + + internal delegate uint StreamCloseDelegate( + IntPtr Stream); + + internal delegate uint StreamShutdownDelegate( + IntPtr Stream, + uint Flags, + ushort ErrorCode); + + internal delegate uint StreamSendDelegate( + IntPtr Stream, + QuicBuffer* Buffers, + uint BufferCount, + uint Flags, + IntPtr ClientSendContext); + + internal delegate uint StreamReceiveCompleteDelegate( + IntPtr Stream, + ulong BufferLength); + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct QuicBuffer + { + internal uint Length; + internal byte* Buffer; + } + + private const ushort IPv4 = 2; + private const ushort IPv6 = 23; + + public static SOCKADDR_INET Convert(IPEndPoint endpoint) + { + var socketAddress = new SOCKADDR_INET(); + var buffer = endpoint.Address.GetAddressBytes(); + if (endpoint.Address != IPAddress.Any && endpoint.Address != IPAddress.IPv6Any) + { + switch (endpoint.Address.AddressFamily) + { + case AddressFamily.InterNetwork: + socketAddress.Ipv4.sin_addr0 = buffer[0]; + socketAddress.Ipv4.sin_addr1 = buffer[1]; + socketAddress.Ipv4.sin_addr2 = buffer[2]; + socketAddress.Ipv4.sin_addr3 = buffer[3]; + socketAddress.Ipv4.sin_family = IPv4; + break; + case AddressFamily.InterNetworkV6: + socketAddress.Ipv6.sin6_addr0 = buffer[0]; + socketAddress.Ipv6.sin6_addr1 = buffer[1]; + socketAddress.Ipv6.sin6_addr2 = buffer[2]; + socketAddress.Ipv6.sin6_addr3 = buffer[3]; + socketAddress.Ipv6.sin6_addr4 = buffer[4]; + socketAddress.Ipv6.sin6_addr5 = buffer[5]; + socketAddress.Ipv6.sin6_addr6 = buffer[6]; + socketAddress.Ipv6.sin6_addr7 = buffer[7]; + socketAddress.Ipv6.sin6_addr8 = buffer[8]; + socketAddress.Ipv6.sin6_addr9 = buffer[9]; + socketAddress.Ipv6.sin6_addr10 = buffer[10]; + socketAddress.Ipv6.sin6_addr11 = buffer[11]; + socketAddress.Ipv6.sin6_addr12 = buffer[12]; + socketAddress.Ipv6.sin6_addr13 = buffer[13]; + socketAddress.Ipv6.sin6_addr14 = buffer[14]; + socketAddress.Ipv6.sin6_addr15 = buffer[15]; + socketAddress.Ipv6.sin6_family = IPv6; + break; + default: + throw new ArgumentException("Only IPv4 or IPv6 are supported"); + } + } + + SetPort(endpoint.Address.AddressFamily, ref socketAddress, endpoint.Port); + return socketAddress; + } + + private static void SetPort(AddressFamily addressFamily, ref SOCKADDR_INET socketAddrInet, int originalPort) + { + var convertedPort = (ushort)IPAddress.HostToNetworkOrder((short)originalPort); + switch (addressFamily) + { + case AddressFamily.InterNetwork: + socketAddrInet.Ipv4.sin_port = convertedPort; + break; + case AddressFamily.InterNetworkV6: + default: + socketAddrInet.Ipv6.sin6_port = convertedPort; + break; + } + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStatusException.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStatusException.cs new file mode 100644 index 0000000000..c58b976482 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStatusException.cs @@ -0,0 +1,42 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class MsQuicStatusException : Exception + { + internal MsQuicStatusException(uint status) + : this(status, null) + { + } + + internal MsQuicStatusException(uint status, string message) + : this(status, message, null) + { + } + + internal MsQuicStatusException(uint status, string message, Exception innerException) + : base(GetMessage(status, message), innerException) + { + Status = status; + } + + internal uint Status { get; } + + private static string GetMessage(uint status, string message) + { + var errorCode = MsQuicConstants.ErrorTypeFromErrorCode(status); + return $"Quic Error: {errorCode}. " + message; + } + + internal static void ThrowIfFailed(uint status, string message = null, Exception innerException = null) + { + if (!MsQuicStatusHelper.Succeeded(status)) + { + throw new MsQuicStatusException(status, message, innerException); + } + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStatusHelper.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStatusHelper.cs new file mode 100644 index 0000000000..23d15965a9 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStatusHelper.cs @@ -0,0 +1,25 @@ +// 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.Runtime.InteropServices; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal static class MsQuicStatusHelper + { + internal static bool Succeeded(uint status) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return status < 0x80000000; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return (int)status <= 0; + } + + return false; + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStream.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStream.cs new file mode 100644 index 0000000000..a384455f45 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicStream.cs @@ -0,0 +1,477 @@ +// 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.Diagnostics; +using System.IO.Pipelines; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.Logging; +using static Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal.MsQuicNativeMethods; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class MsQuicStream : TransportConnection, IQuicStreamFeature + { + private Task _processingTask; + private MsQuicConnection _connection; + private readonly CancellationTokenSource _streamClosedTokenSource = new CancellationTokenSource(); + private IMsQuicTrace _log; + private bool _disposed; + private IntPtr _nativeObjPtr; + private GCHandle _handle; + private StreamCallbackDelegate _delegate; + private string _connectionId; + private long _streamId = -1; + + internal ResettableCompletionSource _resettableCompletion; + private MemoryHandle[] _bufferArrays; + private GCHandle _sendBuffer; + + public MsQuicStream(MsQuicApi api, MsQuicConnection connection, MsQuicTransportContext context, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr) + { + Debug.Assert(connection != null); + + Api = api; + _nativeObjPtr = nativeObjPtr; + + _connection = connection; + MemoryPool = context.Options.MemoryPoolFactory(); + _log = context.Log; + + ConnectionClosed = _streamClosedTokenSource.Token; + + var maxReadBufferSize = context.Options.MaxReadBufferSize.Value; + var maxWriteBufferSize = context.Options.MaxWriteBufferSize.Value; + _resettableCompletion = new ResettableCompletionSource(this); + + // TODO should we allow these PipeScheduler to be configurable here? + var inputOptions = new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, PipeScheduler.Inline, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false); + var outputOptions = new PipeOptions(MemoryPool, PipeScheduler.Inline, PipeScheduler.ThreadPool, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false); + + var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); + + Features.Set<IQuicStreamFeature>(this); + + // TODO populate the ITlsConnectionFeature (requires client certs). + Features.Set<ITlsConnectionFeature>(new FakeTlsConnectionFeature()); + if (flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL)) + { + IsUnidirectional = true; + } + + Transport = pair.Transport; + Application = pair.Application; + + SetCallbackHandler(); + + _processingTask = ProcessSends(); + } + + public override MemoryPool<byte> MemoryPool { get; } + public PipeWriter Input => Application.Output; + public PipeReader Output => Application.Input; + + public bool IsUnidirectional { get; } + + public long StreamId + { + get + { + if (_streamId == -1) + { + _streamId = GetStreamId(); + } + + return _streamId; + } + } + + public override string ConnectionId { + get + { + if (_connectionId == null) + { + _connectionId = $"{_connection.ConnectionId}:{StreamId}"; + } + return _connectionId; + } + set + { + _connectionId = value; + } + } + + private async Task ProcessSends() + { + var output = Output; + try + { + while (true) + { + var result = await output.ReadAsync(); + _log.LogDebug(0, "Handling send event"); + + if (result.IsCanceled) + { + // TODO how to get abort codepath sync'd + ShutDown(QUIC_STREAM_SHUTDOWN_FLAG.ABORT, 0); + break; + } + + var buffer = result.Buffer; + + var end = buffer.End; + var isCompleted = result.IsCompleted; + if (!buffer.IsEmpty) + { + await SendAsync(buffer, QUIC_SEND_FLAG.NONE); + } + + output.AdvanceTo(end); + + if (isCompleted) + { + // Once the stream pipe is closed, shutdown the stream. + ShutDown(QUIC_STREAM_SHUTDOWN_FLAG.GRACEFUL, 0); + break; + } + } + } + catch (Exception) + { + ShutDown(QUIC_STREAM_SHUTDOWN_FLAG.ABORT, 0); + } + } + + internal uint HandleEvent(ref MsQuicNativeMethods.StreamEvent evt) + { + var status = MsQuicConstants.Success; + + switch (evt.Type) + { + case QUIC_STREAM_EVENT.START_COMPLETE: + status = HandleStartComplete(); + break; + case QUIC_STREAM_EVENT.RECV: + { + HandleEventRecv( + ref evt); + } + break; + case QUIC_STREAM_EVENT.SEND_COMPLETE: + { + status = HandleEventSendComplete(ref evt); + } + break; + case QUIC_STREAM_EVENT.PEER_SEND_CLOSE: + { + status = HandleEventPeerSendClose(); + } + break; + // TODO figure out difference between SEND_ABORT and RECEIVE_ABORT + case QUIC_STREAM_EVENT.PEER_SEND_ABORT: + { + _streamClosedTokenSource.Cancel(); + status = HandleEventPeerSendAbort(); + } + break; + case QUIC_STREAM_EVENT.PEER_RECV_ABORT: + { + _streamClosedTokenSource.Cancel(); + status = HandleEventPeerRecvAbort(); + } + break; + case QUIC_STREAM_EVENT.SEND_SHUTDOWN_COMPLETE: + { + status = HandleEventSendShutdownComplete(ref evt); + } + break; + case QUIC_STREAM_EVENT.SHUTDOWN_COMPLETE: + { + Close(); + return MsQuicConstants.Success; + } + + default: + break; + } + return status; + } + + private uint HandleEventPeerRecvAbort() + { + return MsQuicConstants.Success; + } + + private uint HandleEventPeerSendAbort() + { + return MsQuicConstants.Success; + } + + private uint HandleStartComplete() + { + _resettableCompletion.Complete(MsQuicConstants.Success); + return MsQuicConstants.Success; + } + + private uint HandleEventSendShutdownComplete(ref MsQuicNativeMethods.StreamEvent evt) + { + return MsQuicConstants.Success; + } + + private uint HandleEventPeerSendClose() + { + Input.Complete(); + return MsQuicConstants.Success; + } + + public uint HandleEventSendComplete(ref MsQuicNativeMethods.StreamEvent evt) + { + _sendBuffer.Free(); + foreach (var gchBufferArray in _bufferArrays) + { + gchBufferArray.Dispose(); + } + _resettableCompletion.Complete(evt.Data.PeerRecvAbort.ErrorCode); + return MsQuicConstants.Success; + } + + protected void HandleEventRecv(ref MsQuicNativeMethods.StreamEvent evt) + { + static unsafe void CopyToBuffer(Span<byte> buffer, StreamEvent evt) + { + var length = (int)evt.Data.Recv.Buffers[0].Length; + new Span<byte>(evt.Data.Recv.Buffers[0].Buffer, length).CopyTo(buffer); + } + + _log.LogDebug(0, "Handling receive event"); + var input = Input; + var length = (int)evt.Data.Recv.TotalBufferLength; + var result = input.GetSpan(length); + CopyToBuffer(result, evt); + + input.Advance(length); + + var flushTask = input.FlushAsync(); + + if (!flushTask.IsCompletedSuccessfully) + { + _ = AwaitFlush(flushTask); + + return; + } + + async Task AwaitFlush(ValueTask<FlushResult> ft) + { + await ft; + // TODO figure out when to call these for receive. + EnableReceive(); + ReceiveComplete(length); + } + } + + public override void Abort(ConnectionAbortedException abortReason) + { + Shutdown(abortReason); + + // Cancel ProcessSends loop after calling shutdown to ensure the correct _shutdownReason gets set. + Output.CancelPendingRead(); + } + + private void Shutdown(Exception shutdownReason) + { + } + + public MsQuicApi Api { get; set; } + + internal static uint NativeCallbackHandler( + IntPtr stream, + IntPtr context, + StreamEvent connectionEventStruct) + { + var handle = GCHandle.FromIntPtr(context); + var quicStream = (MsQuicStream)handle.Target; + + return quicStream.HandleEvent(ref connectionEventStruct); + } + + public void SetCallbackHandler() + { + _handle = GCHandle.Alloc(this); + + _delegate = new StreamCallbackDelegate(NativeCallbackHandler); + Api.SetCallbackHandlerDelegate( + _nativeObjPtr, + _delegate, + GCHandle.ToIntPtr(_handle)); + } + + public unsafe ValueTask<uint> SendAsync( + ReadOnlySequence<byte> buffers, + QUIC_SEND_FLAG flags) + { + var bufferCount = 0; + foreach (var memory in buffers) + { + bufferCount++; + } + + var quicBufferArray = new QuicBuffer[bufferCount]; + _bufferArrays = new MemoryHandle[bufferCount]; + + var i = 0; + foreach (var memory in buffers) + { + var handle = memory.Pin(); + _bufferArrays[i] = handle; + quicBufferArray[i].Length = (uint)memory.Length; + quicBufferArray[i].Buffer = (byte*)handle.Pointer; + i++; + } + + _sendBuffer = GCHandle.Alloc(quicBufferArray, GCHandleType.Pinned); + + var quicBufferPointer = (QuicBuffer*)Marshal.UnsafeAddrOfPinnedArrayElement(quicBufferArray, 0); + + var status = Api.StreamSendDelegate( + _nativeObjPtr, + quicBufferPointer, + (uint)bufferCount, + (uint)flags, + _nativeObjPtr); + + MsQuicStatusException.ThrowIfFailed(status); + + return _resettableCompletion.GetValueTask(); + } + + public ValueTask<uint> StartAsync() + { + var status = Api.StreamStartDelegate( + _nativeObjPtr, + (uint)QUIC_STREAM_START_FLAG.ASYNC); + + MsQuicStatusException.ThrowIfFailed(status); + return _resettableCompletion.GetValueTask(); + } + + public void ReceiveComplete(int bufferLength) + { + var status = (uint)Api.StreamReceiveComplete(_nativeObjPtr, (ulong)bufferLength); + MsQuicStatusException.ThrowIfFailed(status); + } + + public void ShutDown( + QUIC_STREAM_SHUTDOWN_FLAG flags, + ushort errorCode) + { + var status = (uint)Api.StreamShutdownDelegate( + _nativeObjPtr, + (uint)flags, + errorCode); + MsQuicStatusException.ThrowIfFailed(status); + } + + public void Close() + { + var status = (uint)Api.StreamCloseDelegate?.Invoke(_nativeObjPtr); + MsQuicStatusException.ThrowIfFailed(status); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public unsafe void EnableReceive() + { + var val = true; + var buffer = new QuicBuffer() + { + Length = sizeof(bool), + Buffer = (byte*)&val + }; + SetParam(QUIC_PARAM_STREAM.RECEIVE_ENABLED, buffer); + } + + private unsafe long GetStreamId() + { + byte* ptr = stackalloc byte[sizeof(long)]; + var buffer = new QuicBuffer + { + Length = sizeof(long), + Buffer = ptr + }; + GetParam(QUIC_PARAM_STREAM.ID, buffer); + return *(long*)ptr; + } + + private void GetParam( + QUIC_PARAM_STREAM param, + QuicBuffer buf) + { + MsQuicStatusException.ThrowIfFailed(Api.UnsafeGetParam( + _nativeObjPtr, + (uint)QUIC_PARAM_LEVEL.STREAM, + (uint)param, + ref buf)); + } + + private void SetParam( + QUIC_PARAM_STREAM param, + QuicBuffer buf) + { + MsQuicStatusException.ThrowIfFailed(Api.UnsafeSetParam( + _nativeObjPtr, + (uint)QUIC_PARAM_LEVEL.STREAM, + (uint)param, + buf)); + } + + ~MsQuicStream() + { + Dispose(false); + } + + private void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + if (_nativeObjPtr != IntPtr.Zero) + { + Api.StreamCloseDelegate?.Invoke(_nativeObjPtr); + } + + _handle.Free(); + _nativeObjPtr = IntPtr.Zero; + Api = null; + + _disposed = true; + } + } + + internal class FakeTlsConnectionFeature : ITlsConnectionFeature + { + public FakeTlsConnectionFeature() + { + } + + public X509Certificate2 ClientCertificate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicTrace.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicTrace.cs new file mode 100644 index 0000000000..318e1fddb8 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicTrace.cs @@ -0,0 +1,53 @@ +// 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 Microsoft.Extensions.Logging; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class MsQuicTrace : IMsQuicTrace + { + private static readonly Action<ILogger, string, Exception> _acceptedConnection = + LoggerMessage.Define<string>(LogLevel.Debug, new EventId(4, nameof(NewConnection)), @"Connection id ""{ConnectionId}"" accepted."); + private static readonly Action<ILogger, string, Exception> _acceptedStream = + LoggerMessage.Define<string>(LogLevel.Debug, new EventId(5, nameof(NewStream)), @"Stream id ""{ConnectionId}"" accepted."); + private static readonly Action<ILogger, string, string, Exception> _connectionError = + LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(6, nameof(NewStream)), @"Connection id ""{ConnectionId}"" hit an exception: ""{Reason}""."); + private static readonly Action<ILogger, string, string, Exception> _streamError = + LoggerMessage.Define<string, string>(LogLevel.Debug, new EventId(7, nameof(NewStream)), @"Connection id ""{ConnectionId}"" hit an exception: ""{Reason}""."); + + private ILogger _logger; + + public MsQuicTrace(ILogger logger) + { + _logger = logger; + } + + public IDisposable BeginScope<TState>(TState state) => _logger.BeginScope(state); + + public bool IsEnabled(LogLevel logLevel) => _logger.IsEnabled(logLevel); + + public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) + => _logger.Log(logLevel, eventId, state, exception, formatter); + + public void NewConnection(string connectionId) + { + _acceptedConnection(_logger, connectionId, null); + } + + public void NewStream(string streamId) + { + _acceptedStream(_logger, streamId, null); + } + public void ConnectionError(string connectionId, Exception ex) + { + _connectionError(_logger, connectionId, ex.Message, ex); + } + + public void StreamError(string streamId, Exception ex) + { + _streamError(_logger, streamId, ex.Message, ex); + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicTransportContext.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicTransportContext.cs new file mode 100644 index 0000000000..42612c591b --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/MsQuicTransportContext.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.Extensions.Hosting; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class MsQuicTransportContext + { + public MsQuicTransportContext(IHostApplicationLifetime appLifetime, IMsQuicTrace log, MsQuicTransportOptions options) + { + AppLifetime = appLifetime; + Log = log; + Options = options; + } + + public IHostApplicationLifetime AppLifetime { get; } + public IMsQuicTrace Log { get; } + public MsQuicTransportOptions Options { get; } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/QuicSecConfig.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/QuicSecConfig.cs new file mode 100644 index 0000000000..670efa71b2 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/QuicSecConfig.cs @@ -0,0 +1,44 @@ +// 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; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class QuicSecConfig : IDisposable + { + private bool _disposed; + private MsQuicApi _registration; + + public QuicSecConfig(MsQuicApi registration, IntPtr nativeObjPtr) + { + _registration = registration; + NativeObjPtr = nativeObjPtr; + } + + public IntPtr NativeObjPtr { get; private set; } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + _registration.SecConfigDeleteDelegate?.Invoke(NativeObjPtr); + NativeObjPtr = IntPtr.Zero; + _disposed = true; + } + + ~QuicSecConfig() + { + Dispose(disposing: false); + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/QuicSession.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/QuicSession.cs new file mode 100644 index 0000000000..ba2bf8c868 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/QuicSession.cs @@ -0,0 +1,141 @@ +// 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.Net; +using System.Threading.Tasks; +using static Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal.MsQuicNativeMethods; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal sealed class QuicSession : IDisposable + { + private bool _disposed = false; + private IntPtr _nativeObjPtr; + private MsQuicApi _registration; + + internal QuicSession(MsQuicApi registration, IntPtr nativeObjPtr) + { + _registration = registration; + _nativeObjPtr = nativeObjPtr; + } + + public async ValueTask<MsQuicConnection> ConnectionOpenAsync(IPEndPoint endpoint, MsQuicTransportContext context) + { + var status = _registration.ConnectionOpenDelegate( + _nativeObjPtr, + MsQuicConnection.NativeCallbackHandler, + IntPtr.Zero, + out var connectionPtr); + + MsQuicStatusException.ThrowIfFailed(status); + + var msQuicConnection = new MsQuicConnection(_registration, context, connectionPtr); + + await msQuicConnection.StartAsync((ushort)endpoint.AddressFamily, endpoint.Address.ToString(), (ushort)endpoint.Port); + + return msQuicConnection; + } + + internal IntPtr ListenerOpen(ListenerCallbackDelegate callback) + { + var status = _registration.ListenerOpenDelegate( + _nativeObjPtr, + callback, + IntPtr.Zero, + out var listenerPointer + ); + + MsQuicStatusException.ThrowIfFailed(status); + + return listenerPointer; + } + + public void ShutDown( + QUIC_CONNECTION_SHUTDOWN_FLAG Flags, + ushort ErrorCode) + { + _registration.SessionShutdownDelegate( + _nativeObjPtr, + (uint)Flags, + ErrorCode); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void SetPeerBiDirectionalStreamCount(ushort count) + { + SetUshortParamter(QUIC_PARAM_SESSION.PEER_BIDI_STREAM_COUNT, count); + } + + public void SetPeerUnidirectionalStreamCount(ushort count) + { + SetUshortParamter(QUIC_PARAM_SESSION.PEER_UNIDI_STREAM_COUNT, count); + } + + private unsafe void SetUshortParamter(QUIC_PARAM_SESSION param, ushort count) + { + var buffer = new MsQuicNativeMethods.QuicBuffer() + { + Length = sizeof(ushort), + Buffer = (byte*)&count + }; + + SetParam(param, buffer); + } + + public void SetDisconnectTimeout(TimeSpan timeout) + { + SetULongParamter(QUIC_PARAM_SESSION.DISCONNECT_TIMEOUT, (ulong)timeout.TotalMilliseconds); + } + + public void SetIdleTimeout(TimeSpan timeout) + { + SetULongParamter(QUIC_PARAM_SESSION.IDLE_TIMEOUT, (ulong)timeout.TotalMilliseconds); + + } + private unsafe void SetULongParamter(QUIC_PARAM_SESSION param, ulong count) + { + var buffer = new MsQuicNativeMethods.QuicBuffer() + { + Length = sizeof(ulong), + Buffer = (byte*)&count + }; + SetParam(param, buffer); + } + + private void SetParam( + QUIC_PARAM_SESSION param, + MsQuicNativeMethods.QuicBuffer buf) + { + MsQuicStatusException.ThrowIfFailed(_registration.UnsafeSetParam( + _nativeObjPtr, + (uint)QUIC_PARAM_LEVEL.SESSION, + (uint)param, + buf)); + } + + ~QuicSession() + { + Dispose(false); + } + + private void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + _registration.SessionCloseDelegate?.Invoke(_nativeObjPtr); + _nativeObjPtr = IntPtr.Zero; + _registration = null; + + _disposed = true; + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/ResettableCompletionSource.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/ResettableCompletionSource.cs new file mode 100644 index 0000000000..9c71211f96 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/ResettableCompletionSource.cs @@ -0,0 +1,58 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using System.Threading.Tasks.Sources; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal class ResettableCompletionSource : IValueTaskSource<uint> + { + private ManualResetValueTaskSourceCore<uint> _valueTaskSource; + private readonly MsQuicStream _stream; + + public ResettableCompletionSource(MsQuicStream stream) + { + _stream = stream; + _valueTaskSource.RunContinuationsAsynchronously = true; + } + + public ValueTask<uint> GetValueTask() + { + return new ValueTask<uint>(this, _valueTaskSource.Version); + } + + public uint GetResult(short token) + { + var isValid = token == _valueTaskSource.Version; + try + { + return _valueTaskSource.GetResult(token); + } + finally + { + if (isValid) + { + _valueTaskSource.Reset(); + _stream._resettableCompletion = this; + } + } + } + + public ValueTaskSourceStatus GetStatus(short token) + { + return _valueTaskSource.GetStatus(token); + } + + public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + { + _valueTaskSource.OnCompleted(continuation, state, token, flags); + } + + public void Complete(uint result) + { + _valueTaskSource.SetResult(result); + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Internal/UIntExtensions.cs b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/UIntExtensions.cs new file mode 100644 index 0000000000..31d2b41fb6 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Internal/UIntExtensions.cs @@ -0,0 +1,25 @@ +// 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.Runtime.InteropServices; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal +{ + internal static class UIntExtensions + { + internal static bool Succeeded(this uint status) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return status >= 0x80000000; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return (int)status <= 0; + } + + return false; + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj b/src/Servers/Kestrel/Transport.MsQuic/src/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj new file mode 100644 index 0000000000..c777d59b89 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.csproj @@ -0,0 +1,43 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <Description>Libuv transport for the ASP.NET Core Kestrel cross-platform web server.</Description> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <GenerateDocumentationFile>true</GenerateDocumentationFile> + <PackageTags>aspnetcore;kestrel</PackageTags> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <NoWarn>CS1591;$(NoWarn)</NoWarn> + <IsShippingPackage>false</IsShippingPackage> + </PropertyGroup> + + <ItemGroup> + <Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" /> + <Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" /> + <Compile Include="$(SharedSourceRoot)ServerInfrastructure\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> + <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" /> + <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" Link="Internal\TransportConnection.Generated.cs" /> + <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.FeatureCollection.cs" Link="Internal\TransportConnection.FeatureCollection.cs" /> + </ItemGroup> + + <ItemGroup> + <Reference Include="Microsoft.AspNetCore.Hosting.Abstractions" /> + <Reference Include="Microsoft.AspNetCore.Connections.Abstractions" /> + <Reference Include="Microsoft.Extensions.Logging.Abstractions" /> + <Reference Include="Microsoft.Extensions.Options" /> + </ItemGroup> + + <ItemGroup> + <Content Include="msquic.dll" Condition="Exists('msquic.dll')"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> + </Content> + <Content Include="libmsquic.so" Condition="Exists('libmsquic.so')"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> + </Content> + <Content Include="msquic.pdb" Condition="Exists('msquic.pdb')"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> + </Content> + </ItemGroup> +</Project> diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicConnectionFactory.cs b/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicConnectionFactory.cs new file mode 100644 index 0000000000..98d585935f --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicConnectionFactory.cs @@ -0,0 +1,64 @@ +// 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.Net; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic +{ + public class MsQuicConnectionFactory : IConnectionFactory + { + private MsQuicApi _api; + private QuicSession _session; + private bool _started; + private MsQuicTransportContext _transportContext; + + public MsQuicConnectionFactory(IOptions<MsQuicTransportOptions> options, IHostApplicationLifetime lifetime, ILoggerFactory loggerFactory) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + _api = new MsQuicApi(); + var logger = loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Client"); + var trace = new MsQuicTrace(logger); + + _transportContext = new MsQuicTransportContext(lifetime, trace, options.Value); + } + + public async ValueTask<ConnectionContext> ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken = default) + { + if (!(endPoint is IPEndPoint ipEndPoint)) + { + throw new NotSupportedException($"{endPoint} is not supported"); + } + + if (!_started) + { + _started = true; + await StartAsync(); + } + + var connection = await _session.ConnectionOpenAsync(ipEndPoint, _transportContext); + return connection; + } + + private ValueTask StartAsync() + { + _api.RegistrationOpen(Encoding.ASCII.GetBytes(_transportContext.Options.RegistrationName)); + _session = _api.SessionOpen(_transportContext.Options.Alpn); + _session.SetIdleTimeout(_transportContext.Options.IdleTimeout); + _session.SetPeerBiDirectionalStreamCount(_transportContext.Options.MaxBidirectionalStreamCount); + _session.SetPeerUnidirectionalStreamCount(_transportContext.Options.MaxBidirectionalStreamCount); + return new ValueTask(); + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicTransportFactory.cs b/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicTransportFactory.cs new file mode 100644 index 0000000000..c3200982c5 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicTransportFactory.cs @@ -0,0 +1,47 @@ +// 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.Net; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic +{ + public class MsQuicTransportFactory : IMultiplexedConnectionListenerFactory + { + private MsQuicTrace _log; + private IHostApplicationLifetime _applicationLifetime; + private MsQuicTransportOptions _options; + + public MsQuicTransportFactory(IHostApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory, IOptions<MsQuicTransportOptions> options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (loggerFactory == null) + { + throw new ArgumentNullException(nameof(loggerFactory)); + } + + var logger = loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic"); + _log = new MsQuicTrace(logger); + _applicationLifetime = applicationLifetime; + _options = options.Value; + } + + public async ValueTask<IConnectionListener> BindAsync(EndPoint endpoint, CancellationToken cancellationToken = default) + { + var transport = new MsQuicConnectionListener(_options, _applicationLifetime, _log, endpoint); + await transport.BindAsync(); + return transport; + } + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicTransportOptions.cs b/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicTransportOptions.cs new file mode 100644 index 0000000000..17e3c32f1a --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/MsQuicTransportOptions.cs @@ -0,0 +1,55 @@ +// 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.Security.Cryptography.X509Certificates; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic +{ + public class MsQuicTransportOptions + { + /// <summary> + /// The maximum number of concurrent bi-directional streams per connection. + /// </summary> + public ushort MaxBidirectionalStreamCount { get; set; } = 100; + + /// <summary> + /// The maximum number of concurrent inbound uni-directional streams per connection. + /// </summary> + public ushort MaxUnidirectionalStreamCount { get; set; } = 10; + + /// <summary> + /// The Application Layer Protocol Negotiation string. + /// </summary> + public string Alpn { get; set; } + + /// <summary> + /// The registration name to use in MsQuic. + /// </summary> + public string RegistrationName { get; set; } + + /// <summary> + /// The certificate that MsQuic will use. + /// </summary> + public X509Certificate2 Certificate { get; set; } + + /// <summary> + /// Sets the idle timeout for connections and streams. + /// </summary> + public TimeSpan IdleTimeout { get; set; } + + /// <summary> + /// The maximum read size. + /// </summary> + public long? MaxReadBufferSize { get; set; } = 1024 * 1024; + + /// <summary> + /// The maximum write size. + /// </summary> + public long? MaxWriteBufferSize { get; set; } = 64 * 1024; + + internal Func<MemoryPool<byte>> MemoryPoolFactory { get; set; } = System.Buffers.SlabMemoryPoolFactory.Create; + + } +} diff --git a/src/Servers/Kestrel/Transport.MsQuic/src/WebHostBuilderMsQuicExtensions.cs b/src/Servers/Kestrel/Transport.MsQuic/src/WebHostBuilderMsQuicExtensions.cs new file mode 100644 index 0000000000..15fffe52a6 --- /dev/null +++ b/src/Servers/Kestrel/Transport.MsQuic/src/WebHostBuilderMsQuicExtensions.cs @@ -0,0 +1,30 @@ +// 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 Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic; +using Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic.Internal; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.Hosting +{ + public static class WebHostBuilderMsQuicExtensions + { + public static IWebHostBuilder UseMsQuic(this IWebHostBuilder hostBuilder) + { + return hostBuilder.ConfigureServices(services => + { + services.AddSingleton<IConnectionListenerFactory, MsQuicTransportFactory>(); + }); + } + + public static IWebHostBuilder UseMsQuic(this IWebHostBuilder hostBuilder, Action<MsQuicTransportOptions> configureOptions) + { + return hostBuilder.UseMsQuic().ConfigureServices(services => + { + services.Configure(configureOptions); + }); + } + } +} diff --git a/src/Servers/Kestrel/Transport.Sockets/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.netcoreapp.cs b/src/Servers/Kestrel/Transport.Sockets/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.netcoreapp.cs index c1e32cc39d..a08dc70324 100644 --- a/src/Servers/Kestrel/Transport.Sockets/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.netcoreapp.cs +++ b/src/Servers/Kestrel/Transport.Sockets/ref/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.netcoreapp.cs @@ -19,9 +19,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets public partial class SocketTransportOptions { public SocketTransportOptions() { } - public int IOQueueCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long? MaxReadBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long? MaxWriteBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool NoDelay { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public int Backlog { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int IOQueueCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaxReadBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaxWriteBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool NoDelay { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + } +} +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Client +{ + public partial class SocketConnectionFactory : Microsoft.AspNetCore.Connections.IConnectionFactory, System.IAsyncDisposable + { + public SocketConnectionFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportOptions> options, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } + [System.Diagnostics.DebuggerStepThroughAttribute] + public System.Threading.Tasks.ValueTask<Microsoft.AspNetCore.Connections.ConnectionContext> ConnectAsync(System.Net.EndPoint endpoint, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } } } diff --git a/src/Servers/Kestrel/Transport.Sockets/src/Client/SocketConnectionFactory.cs b/src/Servers/Kestrel/Transport.Sockets/src/Client/SocketConnectionFactory.cs new file mode 100644 index 0000000000..20d5b97018 --- /dev/null +++ b/src/Servers/Kestrel/Transport.Sockets/src/Client/SocketConnectionFactory.cs @@ -0,0 +1,76 @@ +// 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.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Client +{ + public class SocketConnectionFactory : IConnectionFactory, IAsyncDisposable + { + private readonly SocketTransportOptions _options; + private readonly MemoryPool<byte> _memoryPool; + private readonly SocketsTrace _trace; + + public SocketConnectionFactory(IOptions<SocketTransportOptions> options, ILoggerFactory loggerFactory) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (loggerFactory == null) + { + throw new ArgumentNullException(nameof(loggerFactory)); + } + + _options = options.Value; + _memoryPool = options.Value.MemoryPoolFactory(); + var logger = loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Client"); + _trace = new SocketsTrace(logger); + } + + public async ValueTask<ConnectionContext> ConnectAsync(EndPoint endpoint, CancellationToken cancellationToken = default) + { + var ipEndPoint = endpoint as IPEndPoint; + + if (ipEndPoint is null) + { + throw new NotSupportedException("The SocketConnectionFactory only supports IPEndPoints for now."); + } + + var socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) + { + NoDelay = _options.NoDelay + }; + + await socket.ConnectAsync(ipEndPoint); + + var socketConnection = new SocketConnection( + socket, + _memoryPool, + PipeScheduler.ThreadPool, + _trace, + _options.MaxReadBufferSize, + _options.MaxWriteBufferSize); + + socketConnection.Start(); + return socketConnection; + } + + public ValueTask DisposeAsync() + { + _memoryPool.Dispose(); + return default; + } + } +} diff --git a/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj b/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj index 037dcfb6fc..6bb6ff2ce3 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj +++ b/src/Servers/Kestrel/Transport.Sockets/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <Description>Managed socket transport for the ASP.NET Core Kestrel cross-platform web server.</Description> @@ -14,7 +14,7 @@ <ItemGroup> <Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" /> <Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" /> - <Compile Include="$(KestrelSharedSourceRoot)\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> + <Compile Include="$(SharedSourceRoot)ServerInfrastructure\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" Link="Internal\TransportConnection.Generated.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.FeatureCollection.cs" Link="Internal\TransportConnection.FeatureCollection.cs" /> diff --git a/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs b/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs index ccdb774674..f829ae5591 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs @@ -62,6 +62,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets throw new InvalidOperationException(SocketsStrings.TransportAlreadyBound); } + // Check if EndPoint is a FileHandleEndpoint before attempting to access EndPoint.AddressFamily + // since that will throw an NotImplementedException. + if (EndPoint is FileHandleEndPoint) + { + throw new NotSupportedException(SocketsStrings.FileHandleEndPointNotSupported); + } + Socket listenSocket; // Unix domain sockets are unspecified @@ -86,7 +93,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets EndPoint = listenSocket.LocalEndPoint; - listenSocket.Listen(512); + listenSocket.Listen(_options.Backlog); _listenSocket = listenSocket; } diff --git a/src/Servers/Kestrel/Transport.Sockets/src/SocketTransportOptions.cs b/src/Servers/Kestrel/Transport.Sockets/src/SocketTransportOptions.cs index 4adb16ebfb..424a4375ae 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/SocketTransportOptions.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/SocketTransportOptions.cs @@ -24,6 +24,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets /// </remarks> public bool NoDelay { get; set; } = true; + /// <summary> + /// The maximum length of the pending connection queue. + /// </summary> + /// <remarks> + /// Defaults to 512. + /// </remarks> + public int Backlog { get; set; } = 512; + public long? MaxReadBufferSize { get; set; } = 1024 * 1024; public long? MaxWriteBufferSize { get; set; } = 64 * 1024; diff --git a/src/Servers/Kestrel/Transport.Sockets/src/SocketsStrings.resx b/src/Servers/Kestrel/Transport.Sockets/src/SocketsStrings.resx index 52b26c66bc..5f1475a1cf 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/SocketsStrings.resx +++ b/src/Servers/Kestrel/Transport.Sockets/src/SocketsStrings.resx @@ -117,10 +117,13 @@ <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> + <data name="FileHandleEndPointNotSupported" xml:space="preserve"> + <value>The Socket transport does not support binding to file handles. Consider using the libuv transport instead.</value> + </data> <data name="OnlyIPEndPointsSupported" xml:space="preserve"> <value>Only ListenType.IPEndPoint is supported by the Socket Transport. https://go.microsoft.com/fwlink/?linkid=874850</value> </data> <data name="TransportAlreadyBound" xml:space="preserve"> <value>Transport is already bound.</value> </data> -</root> \ No newline at end of file +</root> diff --git a/src/Servers/Kestrel/Transport.Sockets/src/WebHostBuilderSocketExtensions.cs b/src/Servers/Kestrel/Transport.Sockets/src/WebHostBuilderSocketExtensions.cs index d073f91aa4..8ee49f198d 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/WebHostBuilderSocketExtensions.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/WebHostBuilderSocketExtensions.cs @@ -8,6 +8,9 @@ using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Hosting { + /// <summary> + /// <see cref="IWebHostBuilder" /> extension methods to configure the Socket transport to be used by Kestrel. + /// </summary> public static class WebHostBuilderSocketExtensions { /// <summary> diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs index 887aad3939..c165c141ce 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Http1ConnectionBenchmark.cs @@ -4,12 +4,14 @@ using System; using System.Buffers; using System.IO.Pipelines; +using System.Net.Http; using BenchmarkDotNet.Attributes; 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 HttpMethod = Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod; namespace Microsoft.AspNetCore.Server.Kestrel.Performance { @@ -104,10 +106,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance RequestHandler = requestHandler; } - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) => RequestHandler.Connection.OnHeader(name, value); - public void OnHeadersComplete() + public void OnHeadersComplete(bool endStream) => RequestHandler.Connection.OnHeadersComplete(); public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded) diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs index c5eb24baf8..2ed922386f 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/HttpParserBenchmark.cs @@ -3,8 +3,10 @@ using System; using System.Buffers; +using System.Net.Http; using BenchmarkDotNet.Attributes; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using HttpMethod = Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod; namespace Microsoft.AspNetCore.Server.Kestrel.Performance { @@ -69,11 +71,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { } - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { } - public void OnHeadersComplete() + public void OnHeadersComplete(bool endStream) { } @@ -86,11 +88,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance RequestHandler = requestHandler; } - public void OnHeader(Span<byte> name, Span<byte> value) + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) => RequestHandler.OnHeader(name, value); - public void OnHeadersComplete() - => RequestHandler.OnHeadersComplete(); + public void OnHeadersComplete(bool endStream) + => RequestHandler.OnHeadersComplete(endStream); 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); diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/IntegerDecoderBenchmark.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/IntegerDecoderBenchmark.cs index 6fc22390c0..e41d076ec6 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/IntegerDecoderBenchmark.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/IntegerDecoderBenchmark.cs @@ -1,8 +1,8 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Net.Http.HPack; using BenchmarkDotNet.Attributes; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; namespace Microsoft.AspNetCore.Server.Kestrel.Performance { diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj b/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj index 61d180a73c..df7255d954 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> @@ -16,7 +16,6 @@ <Compile Include="$(KestrelSharedSourceRoot)test\TestKestrelTrace.cs" /> <Compile Include="..\..\Transport.Sockets\src\Internal\IOQueue.cs" Link="Internal\IOQueue.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" /> - <Compile Include="$(KestrelSharedSourceRoot)\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" Link="Internal\TransportConnection.Generated.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.FeatureCollection.cs" Link="Internal\TransportConnection.FeatureCollection.cs" /> diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs index d2514f998f..bd93636c83 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net.Http.HPack; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void NotAllConnectionsAborted() { } public void NotAllConnectionsClosedGracefully() { } public void RequestProcessingError(string connectionId, Exception ex) { } - public void HeartbeatSlow(TimeSpan interval, DateTimeOffset now) { } + public void HeartbeatSlow(TimeSpan heartbeatDuration, TimeSpan interval, DateTimeOffset now) { } public void ApplicationNeverCompleted(string connectionId) { } public void RequestBodyStart(string connectionId, string traceIdentifier) { } public void RequestBodyDone(string connectionId, string traceIdentifier) { } diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs index 288588f3b1..53bae7b1b5 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullParser.cs @@ -3,8 +3,10 @@ using System; using System.Buffers; +using System.Net.Http; using System.Text; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using HttpMethod = Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpMethod; namespace Microsoft.AspNetCore.Server.Kestrel.Performance { @@ -26,7 +28,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance 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>(_connectionHeaderName), new Span<byte>(_connectionHeaderValue)); - handler.OnHeadersComplete(); + handler.OnHeadersComplete(endStream: false); return true; } diff --git a/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.json.json b/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.json.json index 8313f994bd..4e32992833 100644 --- a/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.json.json +++ b/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.json.json @@ -4,7 +4,7 @@ "PresetHeaders": "Json", "Source": { - "Repository": "https://github.com/aspnet/AspNetCore.git", + "Repository": "https://github.com/dotnet/aspnetcore.git", "BranchOrCommit": "master", "Project": "src/Servers/Kestrel/perf/PlatformBenchmarks/PlatformBenchmarks.csproj" } diff --git a/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.plaintext.json b/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.plaintext.json index 6cfe040ea4..90e570399b 100644 --- a/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.plaintext.json +++ b/src/Servers/Kestrel/perf/PlatformBenchmarks/benchmarks.plaintext.json @@ -7,7 +7,7 @@ "PipelineDepth": 16 }, "Source": { - "Repository": "https://github.com/aspnet/AspNetCore.git", + "Repository": "https://github.com/dotnet/aspnetcore.git", "BranchOrCommit": "master", "Project": "src/Servers/Kestrel/perf/PlatformBenchmarks/PlatformBenchmarks.csproj" }, diff --git a/src/Servers/Kestrel/samples/Http2SampleApp/Program.cs b/src/Servers/Kestrel/samples/Http2SampleApp/Program.cs index c6b37eb216..2b26fe09c6 100644 --- a/src/Servers/Kestrel/samples/Http2SampleApp/Program.cs +++ b/src/Servers/Kestrel/samples/Http2SampleApp/Program.cs @@ -28,13 +28,13 @@ namespace Http2SampleApp var basePort = context.Configuration.GetValue<int?>("BASE_PORT") ?? 5000; // Http/1.1 endpoint for comparison - options.Listen(IPAddress.Any, basePort, listenOptions => + options.ListenAnyIP(basePort, listenOptions => { listenOptions.Protocols = HttpProtocols.Http1; }); // TLS Http/1.1 or HTTP/2 endpoint negotiated via ALPN - options.Listen(IPAddress.Any, basePort + 1, listenOptions => + options.ListenAnyIP(basePort + 1, listenOptions => { listenOptions.Protocols = HttpProtocols.Http1AndHttp2; listenOptions.UseHttps(); @@ -56,7 +56,7 @@ namespace Http2SampleApp // Prior knowledge, no TLS handshake. WARNING: Not supported by browsers // but useful for the h2spec tests - options.Listen(IPAddress.Any, basePort + 5, listenOptions => + options.ListenAnyIP(basePort + 5, listenOptions => { listenOptions.Protocols = HttpProtocols.Http2; }); diff --git a/src/Servers/Kestrel/samples/Http3SampleApp/Http3SampleApp.csproj b/src/Servers/Kestrel/samples/Http3SampleApp/Http3SampleApp.csproj new file mode 100644 index 0000000000..4bc61b8465 --- /dev/null +++ b/src/Servers/Kestrel/samples/Http3SampleApp/Http3SampleApp.csproj @@ -0,0 +1,14 @@ +<Project Sdk="Microsoft.NET.Sdk.Web"> + + <PropertyGroup> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <IsPackable>false</IsPackable> + </PropertyGroup> + + <ItemGroup> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel" /> + <Reference Include="Microsoft.Extensions.Logging.Console" /> + <Reference Include="Microsoft.Extensions.Hosting" /> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic" /> + </ItemGroup> +</Project> diff --git a/src/Servers/Kestrel/samples/Http3SampleApp/Program.cs b/src/Servers/Kestrel/samples/Http3SampleApp/Program.cs new file mode 100644 index 0000000000..9b39054948 --- /dev/null +++ b/src/Servers/Kestrel/samples/Http3SampleApp/Program.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.AspNetCore.Server.Kestrel.Https; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Http3SampleApp +{ + public class Program + { + public static void Main(string[] args) + { + var cert = CertificateLoader.LoadFromStoreCert("localhost", StoreName.My.ToString(), StoreLocation.CurrentUser, true); + var hostBuilder = new HostBuilder() + .ConfigureLogging((_, factory) => + { + factory.SetMinimumLevel(LogLevel.Trace); + factory.AddConsole(); + }) + .ConfigureWebHost(webHost => + { + webHost.UseKestrel() + // Things like APLN and cert should be able to be passed from corefx into bedrock + .UseMsQuic(options => + { + options.Certificate = cert; + options.RegistrationName = "Quic"; + options.Alpn = "h3-24"; + options.IdleTimeout = TimeSpan.FromHours(1); + }) + .ConfigureKestrel((context, options) => + { + var basePort = 5555; + + options.Listen(IPAddress.Any, basePort, listenOptions => + { + listenOptions.UseHttps(); + listenOptions.Protocols = HttpProtocols.Http3; + }); + }) + .UseStartup<Startup>(); + }); + + hostBuilder.Build().Run(); + } + } +} diff --git a/src/Servers/Kestrel/samples/Http3SampleApp/Startup.cs b/src/Servers/Kestrel/samples/Http3SampleApp/Startup.cs new file mode 100644 index 0000000000..0434605cfc --- /dev/null +++ b/src/Servers/Kestrel/samples/Http3SampleApp/Startup.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace Http3SampleApp +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app) + { + app.Run(async context => + { + var memory = new Memory<byte>(new byte[4096]); + var length = await context.Request.Body.ReadAsync(memory); + context.Response.Headers["test"] = "foo"; + // for testing + await context.Response.WriteAsync("Hello World! " + context.Request.Protocol); + }); + } + } +} diff --git a/src/Servers/Kestrel/samples/Http3SampleApp/appsettings.Development.json b/src/Servers/Kestrel/samples/Http3SampleApp/appsettings.Development.json new file mode 100644 index 0000000000..e203e9407e --- /dev/null +++ b/src/Servers/Kestrel/samples/Http3SampleApp/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/src/Servers/Kestrel/samples/Http3SampleApp/appsettings.json b/src/Servers/Kestrel/samples/Http3SampleApp/appsettings.json new file mode 100644 index 0000000000..d9d9a9bff6 --- /dev/null +++ b/src/Servers/Kestrel/samples/Http3SampleApp/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/src/Servers/Kestrel/samples/QuicSampleApp/Program.cs b/src/Servers/Kestrel/samples/QuicSampleApp/Program.cs new file mode 100644 index 0000000000..e5600d06ff --- /dev/null +++ b/src/Servers/Kestrel/samples/QuicSampleApp/Program.cs @@ -0,0 +1,106 @@ +using System; +using System.Buffers; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Https; +using Microsoft.Extensions.Logging; +using System.Diagnostics; +using Microsoft.AspNetCore.Server.Kestrel.Core; + +namespace QuicSampleApp +{ + public class Startup + { + public void Configure(IApplicationBuilder app) + { + app.Run((httpContext) => + { + return Task.CompletedTask; + }); + } + + public static void Main(string[] args) + { + var cert = CertificateLoader.LoadFromStoreCert("localhost", StoreName.My.ToString(), StoreLocation.CurrentUser, true); + var hostBuilder = new WebHostBuilder() + .ConfigureLogging((_, factory) => + { + factory.SetMinimumLevel(LogLevel.Debug); + factory.AddConsole(); + }) + .UseKestrel() + .UseMsQuic(options => + { + options.Certificate = cert; + options.RegistrationName = "AspNetCore-MsQuic"; + options.Alpn = "QuicTest"; + options.IdleTimeout = TimeSpan.FromHours(1); + }) + .ConfigureKestrel((context, options) => + { + var basePort = 5555; + + options.Listen(IPAddress.Any, basePort, listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http3; + listenOptions.Use((next) => + { + return async connection => + { + var streamFeature = connection.Features.Get<IQuicStreamListenerFeature>(); + if (streamFeature != null) + { + while (true) + { + var connectionContext = await streamFeature.AcceptAsync(); + if (connectionContext == null) + { + return; + } + _ = next(connectionContext); + } + } + else + { + await next(connection); + } + }; + }); + + async Task EchoServer(ConnectionContext connection) + { + // For graceful shutdown + try + { + while (true) + { + var result = await connection.Transport.Input.ReadAsync(); + + if (result.IsCompleted) + { + break; + } + + await connection.Transport.Output.WriteAsync(result.Buffer.ToArray()); + + connection.Transport.Input.AdvanceTo(result.Buffer.End); + } + } + catch (OperationCanceledException) + { + } + } + listenOptions.Run(EchoServer); + }); + }) + .UseStartup<Startup>(); + + hostBuilder.Build().Run(); + } + } +} diff --git a/src/Servers/Kestrel/samples/QuicSampleApp/QuicSampleApp.csproj b/src/Servers/Kestrel/samples/QuicSampleApp/QuicSampleApp.csproj new file mode 100644 index 0000000000..4a5ee8de15 --- /dev/null +++ b/src/Servers/Kestrel/samples/QuicSampleApp/QuicSampleApp.csproj @@ -0,0 +1,16 @@ +<Project Sdk="Microsoft.NET.Sdk.Web"> + + <PropertyGroup> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <IsPackable>false</IsPackable> + <NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile> + <GenerateRazorAssemblyInfo>false</GenerateRazorAssemblyInfo> + </PropertyGroup> + + <ItemGroup> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel" /> + <Reference Include="Microsoft.Extensions.Logging.Console" /> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic" /> + </ItemGroup> + +</Project> diff --git a/src/Servers/Kestrel/samples/QuicSampleApp/appsettings.Development.json b/src/Servers/Kestrel/samples/QuicSampleApp/appsettings.Development.json new file mode 100644 index 0000000000..e203e9407e --- /dev/null +++ b/src/Servers/Kestrel/samples/QuicSampleApp/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/src/Servers/Kestrel/samples/QuicSampleApp/appsettings.json b/src/Servers/Kestrel/samples/QuicSampleApp/appsettings.json new file mode 100644 index 0000000000..d9d9a9bff6 --- /dev/null +++ b/src/Servers/Kestrel/samples/QuicSampleApp/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/src/Servers/Kestrel/samples/QuicSampleClient/Program.cs b/src/Servers/Kestrel/samples/QuicSampleClient/Program.cs new file mode 100644 index 0000000000..b1b656cc4e --- /dev/null +++ b/src/Servers/Kestrel/samples/QuicSampleClient/Program.cs @@ -0,0 +1,108 @@ +using System; +using System.Buffers; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Server.Kestrel.Https; +using Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic; +using Microsoft.AspNetCore.Connections.Abstractions.Features; +using Microsoft.Extensions.Hosting; +using Microsoft.AspNetCore.Connections; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.DependencyInjection; + +namespace QuicSampleClient +{ + class Program + { + static async Task Main(string[] args) + { + var host = new HostBuilder() + .ConfigureLogging(loggingBuilder => + { + loggingBuilder.AddConsole(); + loggingBuilder.SetMinimumLevel(LogLevel.Error); + }) + .ConfigureServices(services => + { + services.AddSingleton<IConnectionFactory, MsQuicConnectionFactory>(); + services.AddSingleton<MsQuicClientService>(); + services.AddOptions<MsQuicTransportOptions>(); + services.Configure<MsQuicTransportOptions>((options) => + { + options.Alpn = "QuicTest"; + options.RegistrationName = "Quic-AspNetCore-client"; + options.Certificate = CertificateLoader.LoadFromStoreCert("localhost", StoreName.My.ToString(), StoreLocation.CurrentUser, true); + options.IdleTimeout = TimeSpan.FromHours(1); + }); + }) + .Build(); + await host.Services.GetService<MsQuicClientService>().RunAsync(); + } + + private class MsQuicClientService + { + private readonly IConnectionFactory _connectionFactory; + private readonly ILogger<MsQuicClientService> _logger; + public MsQuicClientService(IConnectionFactory connectionFactory, ILogger<MsQuicClientService> logger) + { + _connectionFactory = connectionFactory; + _logger = logger; + } + + public async Task RunAsync() + { + var start = Console.ReadLine(); + Console.WriteLine("Starting"); + var connectionContext = await _connectionFactory.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 5555)); + var createStreamFeature = connectionContext.Features.Get<IQuicCreateStreamFeature>(); + var streamContext = await createStreamFeature.StartBidirectionalStreamAsync(); + + Console.CancelKeyPress += new ConsoleCancelEventHandler((sender, args) => + { + streamContext.Transport.Input.CancelPendingRead(); + streamContext.Transport.Output.CancelPendingFlush(); + }); + + var input = "asdf"; + while (true) + { + try + { + //var input = Console.ReadLine(); + if (input.Length == 0) + { + continue; + } + var flushResult = await streamContext.Transport.Output.WriteAsync(Encoding.ASCII.GetBytes(input)); + if (flushResult.IsCanceled) + { + break; + } + + var readResult = await streamContext.Transport.Input.ReadAsync(); + if (readResult.IsCanceled) + { + break; + } + if (readResult.Buffer.Length > 0) + { + Console.WriteLine(Encoding.ASCII.GetString(readResult.Buffer.ToArray())); + } + + streamContext.Transport.Input.AdvanceTo(readResult.Buffer.End); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + break; + } + } + + await streamContext.Transport.Input.CompleteAsync(); + await streamContext.Transport.Output.CompleteAsync(); + } + } + } +} diff --git a/src/Servers/Kestrel/samples/QuicSampleClient/QuicSampleClient.csproj b/src/Servers/Kestrel/samples/QuicSampleClient/QuicSampleClient.csproj new file mode 100644 index 0000000000..6477f0dcb3 --- /dev/null +++ b/src/Servers/Kestrel/samples/QuicSampleClient/QuicSampleClient.csproj @@ -0,0 +1,15 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> + <IsPackable>false</IsPackable> + </PropertyGroup> + + <ItemGroup> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.MsQuic" /> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel" /> + <Reference Include="Microsoft.Extensions.Hosting" /> + <Reference Include="Microsoft.Extensions.Logging.Console" /> + </ItemGroup> +</Project> diff --git a/src/Servers/Kestrel/samples/http2cat/Program.cs b/src/Servers/Kestrel/samples/http2cat/Program.cs new file mode 100644 index 0000000000..f7a8634bda --- /dev/null +++ b/src/Servers/Kestrel/samples/http2cat/Program.cs @@ -0,0 +1,81 @@ +// 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.Diagnostics; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http2Cat; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace http2cat +{ + public class Program + { + public static async Task Main(string[] args) + { + using var host = new HostBuilder() + .ConfigureLogging(loggingBuilder => + { + loggingBuilder.AddConsole(); + }) + .UseHttp2Cat("https://localhost:5001", RunTestCase) + .Build(); + + await host.RunAsync(); + } + + internal static async Task RunTestCase(Http2Utilities h2Connection) + { + await h2Connection.InitializeConnectionAsync(); + + h2Connection.Logger.LogInformation("Initialized http2 connection. Starting stream 1."); + + await h2Connection.StartStreamAsync(1, Http2Utilities.BrowserRequestHeaders, endStream: true); + + var headersFrame = await h2Connection.ReceiveFrameAsync(); + + Trace.Assert(headersFrame.Type == Http2FrameType.HEADERS, headersFrame.Type.ToString()); + Trace.Assert((headersFrame.Flags & (byte)Http2HeadersFrameFlags.END_HEADERS) != 0); + Trace.Assert((headersFrame.Flags & (byte)Http2HeadersFrameFlags.END_STREAM) == 0); + + h2Connection.Logger.LogInformation("Received headers in a single frame."); + + var decodedHeaders = h2Connection.DecodeHeaders(headersFrame); + + foreach (var header in decodedHeaders) + { + h2Connection.Logger.LogInformation($"{header.Key}: {header.Value}"); + } + + var dataFrame = await h2Connection.ReceiveFrameAsync(); + + Trace.Assert(dataFrame.Type == Http2FrameType.DATA); + Trace.Assert((dataFrame.Flags & (byte)Http2DataFrameFlags.END_STREAM) == 0); + + h2Connection.Logger.LogInformation("Received data in a single frame."); + + h2Connection.Logger.LogInformation(Encoding.UTF8.GetString(dataFrame.Payload.ToArray())); + + var trailersFrame = await h2Connection.ReceiveFrameAsync(); + + Trace.Assert(trailersFrame.Type == Http2FrameType.HEADERS); + Trace.Assert((trailersFrame.Flags & (byte)Http2DataFrameFlags.END_STREAM) == 1); + + h2Connection.Logger.LogInformation("Received trailers in a single frame."); + + h2Connection.ResetHeaders(); + var decodedTrailers = h2Connection.DecodeHeaders(trailersFrame); + + foreach (var header in decodedTrailers) + { + h2Connection.Logger.LogInformation($"{header.Key}: {header.Value}"); + } + + await h2Connection.StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + + h2Connection.Logger.LogInformation("Connection stopped."); + } + } +} diff --git a/src/Servers/Kestrel/samples/http2cat/http2cat.csproj b/src/Servers/Kestrel/samples/http2cat/http2cat.csproj new file mode 100644 index 0000000000..f668fcfcf0 --- /dev/null +++ b/src/Servers/Kestrel/samples/http2cat/http2cat.csproj @@ -0,0 +1,39 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>netcoreapp5.0</TargetFramework> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + + <ItemGroup> + <Compile Include="$(SharedSourceRoot)Http2\**\*.cs" LinkBase="Shared\Http2\" /> + <Compile Include="$(SharedSourceRoot)Http2cat\**\*.cs" LinkBase="Shared\Http2cat" /> + <Compile Include="$(SharedSourceRoot)ServerInfrastructure\**\*.cs" LinkBase="Shared\" /> + <Compile Include="$(SharedSourceRoot)TaskToApm.cs" Link="Shared\TaskToApm.cs" /> + </ItemGroup> + + <ItemGroup> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets" /> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel.Core" /> + <Reference Include="Microsoft.Extensions.Hosting" /> + <Reference Include="Microsoft.Extensions.Logging.Console" /> + </ItemGroup> + + <ItemGroup> + <EmbeddedResource Include="$(SharedSourceRoot)ServerInfrastructure\SharedStrings.resx" Link="Shared\SharedStrings.resx"> + <ManifestResourceName>Microsoft.AspNetCore.Server.SharedStrings</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> + <EmbeddedResource Include="$(SharedSourceRoot)Http2\SR.resx" Link="Shared\Http2\SR.resx"> + <ManifestResourceName>System.Net.Http.SR</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> + </ItemGroup> + + <ItemGroup> + <None Include="TaskTimeoutExtensions.cs" /> + </ItemGroup> + +</Project> + \ No newline at end of file diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index e38dfb19a9..f26fb786d5 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -145,6 +145,7 @@ namespace CodeGenerator { "Accept-Ranges", "Age", + "Alt-Svc", "ETag", "Location", "Proxy-Authenticate", @@ -951,7 +952,7 @@ $@" private void Clear(long bitsToClear) }} while (tempBits != 0); }}" : "")}{(loop.ClassName == "HttpRequestHeaders" ? $@" [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public unsafe void Append(Span<byte> name, Span<byte> value) + public unsafe void Append(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) {{ ref byte nameStart = ref MemoryMarshal.GetReference(name); ref StringValues values = ref Unsafe.AsRef<StringValues>(null); diff --git a/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs b/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs index f4b55a18a6..85a7643202 100644 --- a/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs +++ b/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Net.Http.HPack; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Logging; @@ -122,10 +122,10 @@ namespace Microsoft.AspNetCore.Testing _trace2.NotAllConnectionsAborted(); } - public void HeartbeatSlow(TimeSpan interval, DateTimeOffset now) + public void HeartbeatSlow(TimeSpan heartbeatDuration, TimeSpan interval, DateTimeOffset now) { - _trace1.HeartbeatSlow(interval, now); - _trace2.HeartbeatSlow(interval, now); + _trace1.HeartbeatSlow(heartbeatDuration, interval, now); + _trace2.HeartbeatSlow(heartbeatDuration, interval, now); } public void ApplicationNeverCompleted(string connectionId) diff --git a/src/Servers/Kestrel/shared/test/TransportTestHelpers/TestServer.cs b/src/Servers/Kestrel/shared/test/TransportTestHelpers/TestServer.cs index d79a6d9055..7ff959bb1f 100644 --- a/src/Servers/Kestrel/shared/test/TransportTestHelpers/TestServer.cs +++ b/src/Servers/Kestrel/shared/test/TransportTestHelpers/TestServer.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; using System.Net; using System.Reflection; @@ -89,7 +90,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests c.Configure(context.ServerOptions); } - return new KestrelServer(sp.GetRequiredService<IConnectionListenerFactory>(), context); + return new KestrelServer(new List<IConnectionListenerFactory>() { sp.GetRequiredService<IConnectionListenerFactory>() }, context); }); configureServices(services); }) diff --git a/src/Servers/Kestrel/stress/Program.cs b/src/Servers/Kestrel/stress/Program.cs index 8bddf0cddb..c962d5bfd7 100644 --- a/src/Servers/Kestrel/stress/Program.cs +++ b/src/Servers/Kestrel/stress/Program.cs @@ -237,7 +237,7 @@ public class Program using (HttpResponseMessage m = await ctx.HttpClient.SendAsync(req)) { ValidateResponse(m, httpVersion); - ValidateContent(content, await m.Content.ReadAsStringAsync());; + ValidateContent(content, await m.Content.ReadAsStringAsync()); } }), diff --git a/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs b/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs index 205bdbbe5f..1c3cd26d0d 100644 --- a/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs +++ b/src/Servers/Kestrel/test/BindTests/AddressRegistrationTests.cs @@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests [ConditionalFact] [HostNameIsReachable] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7267")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/7267")] public async Task RegisterAddresses_HostName_Success() { var hostName = Dns.GetHostName(); @@ -338,7 +338,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests [ConditionalFact] [HostNameIsReachable] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7267")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/7267")] public async Task ListenAnyIP_HostName_Success() { var hostName = Dns.GetHostName(); diff --git a/src/Servers/Kestrel/test/FunctionalTests/Http2/HandshakeTests.cs b/src/Servers/Kestrel/test/FunctionalTests/Http2/HandshakeTests.cs index aaf101cced..66a31011bb 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/Http2/HandshakeTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/Http2/HandshakeTests.cs @@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 [ConditionalFact] [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)] - [OSSkipCondition(OperatingSystems.Windows, WindowsVersions.Win10, WindowsVersions.Win81)] + [MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win7)] // Win7 SslStream is missing ALPN support. public void TlsAndHttp2NotSupportedOnWin7() { @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 [ConditionalFact] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492")] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win81)] public async Task TlsAlpnHandshakeSelectsHttp2From1and2() { @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 [ConditionalFact] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492")] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win81)] public async Task TlsAlpnHandshakeSelectsHttp2() { diff --git a/src/Servers/Kestrel/test/FunctionalTests/Http2/ShutdownTests.cs b/src/Servers/Kestrel/test/FunctionalTests/Http2/ShutdownTests.cs index af2b768fd1..fe219d4ddb 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/Http2/ShutdownTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/Http2/ShutdownTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 { [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492")] [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10)] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 public class ShutdownTests : TestApplicationErrorLoggerLoggedTest { private static X509Certificate2 _x509Certificate2 = TestResources.GetTestCertificate(); @@ -44,8 +44,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 [CollectDump] [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/9985", Queues = "Fedora.28.Amd64.Open")] - [Flaky("https://github.com/aspnet/AspNetCore/issues/9985", FlakyOn.All)] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/9985", Queues = "Fedora.28.Amd64.Open")] + [Flaky("https://github.com/dotnet/aspnetcore/issues/9985", FlakyOn.All)] public async Task GracefulShutdownWaitsForRequestsToFinish() { var requestStarted = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); @@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 await stopTask.DefaultTimeout(); } - Assert.Contains(TestApplicationErrorLogger.Messages, m => m.Message.Contains("Request finished in")); + Assert.Contains(TestApplicationErrorLogger.Messages, m => m.Message.Contains("Request finished ")); Assert.Contains(TestApplicationErrorLogger.Messages, m => m.Message.Contains("is closing.")); Assert.Contains(TestApplicationErrorLogger.Messages, m => m.Message.Contains("is closed. The last processed stream ID was 1.")); } @@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests.Http2 await requestStarted.Task.DefaultTimeout(); // Wait for the graceful shutdown log before canceling the token passed to StopAsync and triggering an ungraceful shutdown. - // Otherwise, graceful shutdown might be skipped causing there to be no corresponding log. https://github.com/aspnet/AspNetCore/issues/6556 + // Otherwise, graceful shutdown might be skipped causing there to be no corresponding log. https://github.com/dotnet/aspnetcore/issues/6556 var closingMessageTask = TestApplicationErrorLogger.WaitForMessage(m => m.Message.Contains("is closing.")).DefaultTimeout(); var cts = new CancellationTokenSource(); diff --git a/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs b/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs index 6e4a5b8803..66ce566288 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs @@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests [ConditionalFact] [IPv6SupportedCondition] #if LIBUV - [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1977", FlakyOn.Helix.All)] // https://github.com/aspnet/AspNetCore/issues/8109 + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/1977", FlakyOn.Helix.All)] // https://github.com/dotnet/aspnetcore/issues/8109 #endif public Task RemoteIPv6Address() { diff --git a/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs b/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs index d3fa68a1bd..c020d401ab 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs @@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Https; using Microsoft.AspNetCore.Server.Kestrel.Https.Internal; @@ -732,7 +733,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } } - [Fact] + [ConditionalFact] + [Flaky("https://github.com/aspnet/AspNetCore-Internal/issues/2181", FlakyOn.All)] public async Task ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseChunks() { var chunkSize = 64 * 128 * 1024; @@ -755,6 +757,176 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests }; testContext.InitializeHeartbeat(); + var dateHeaderValueManager = new DateHeaderValueManager(); + dateHeaderValueManager.OnHeartbeat(DateTimeOffset.MinValue); + testContext.DateHeaderValueManager = dateHeaderValueManager; + + var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); + + async Task App(HttpContext context) + { + context.RequestAborted.Register(() => + { + requestAborted = true; + }); + + for (var i = 0; i < chunkCount; i++) + { + await context.Response.BodyWriter.WriteAsync(new Memory<byte>(chunkData, 0, chunkData.Length), context.RequestAborted); + } + + appFuncCompleted.SetResult(null); + } + + using (var server = new TestServer(App, testContext, listenOptions)) + { + using (var connection = server.CreateConnection()) + { + // Close the connection with the last request so AssertStreamCompleted actually completes. + await connection.Send( + "GET / HTTP/1.1", + "Host:", + "", + ""); + + await connection.Receive( + "HTTP/1.1 200 OK", + $"Date: {dateHeaderValueManager.GetDateHeaderValues().String}"); + + // Make sure consuming a single chunk exceeds the 2 second timeout. + var targetBytesPerSecond = chunkSize / 4; + + // expectedBytes was determined by manual testing. A constant Date header is used, so this shouldn't change unless + // the response header writing logic or response body chunking logic itself changes. + await AssertBytesReceivedAtTargetRate(connection.Stream, expectedBytes: 33_553_537, targetBytesPerSecond); + await appFuncCompleted.Task.DefaultTimeout(); + + connection.ShutdownSend(); + await connection.WaitForConnectionClose(); + } + await server.StopAsync(); + } + + mockKestrelTrace.Verify(t => t.ResponseMinimumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>()), Times.Never()); + mockKestrelTrace.Verify(t => t.ConnectionStop(It.IsAny<string>()), Times.Once()); + Assert.False(requestAborted); + } + + [Fact] + [CollectDump] + public async Task ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseHeaders() + { + var headerSize = 1024 * 1024; // 1 MB for each header value + var headerCount = 64; // 64 MB of headers per response + var requestCount = 4; // Minimum of 256 MB of total response headers + var headerValue = new string('a', headerSize); + var headerStringValues = new StringValues(Enumerable.Repeat(headerValue, headerCount).ToArray()); + + var requestAborted = false; + var mockKestrelTrace = new Mock<IKestrelTrace>(); + + var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) + { + ServerOptions = + { + Limits = + { + MinResponseDataRate = new MinDataRate(bytesPerSecond: 240, gracePeriod: TimeSpan.FromSeconds(2)) + } + } + }; + + testContext.InitializeHeartbeat(); + var dateHeaderValueManager = new DateHeaderValueManager(); + dateHeaderValueManager.OnHeartbeat(DateTimeOffset.MinValue); + testContext.DateHeaderValueManager = dateHeaderValueManager; + + var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); + + async Task App(HttpContext context) + { + context.RequestAborted.Register(() => + { + requestAborted = true; + }); + + context.Response.Headers[$"X-Custom-Header"] = headerStringValues; + context.Response.ContentLength = 0; + + await context.Response.BodyWriter.FlushAsync(); + } + + using (var server = new TestServer(App, testContext, listenOptions)) + { + using (var connection = server.CreateConnection()) + { + for (var i = 0; i < requestCount - 1; i++) + { + await connection.Send( + "GET / HTTP/1.1", + "Host:", + "", + ""); + } + + await connection.Send( + "GET / HTTP/1.1", + "Host:", + "", + ""); + + await connection.Receive( + "HTTP/1.1 200 OK", + $"Date: {dateHeaderValueManager.GetDateHeaderValues().String}"); + + var minResponseSize = headerSize * headerCount; + var minTotalOutputSize = requestCount * minResponseSize; + + // Make sure consuming a single set of response headers exceeds the 2 second timeout. + var targetBytesPerSecond = minResponseSize / 4; + + // expectedBytes was determined by manual testing. A constant Date header is used, so this shouldn't change unless + // the response header writing logic itself changes. + await AssertBytesReceivedAtTargetRate(connection.Stream, expectedBytes: 268_439_596, targetBytesPerSecond); + connection.ShutdownSend(); + await connection.WaitForConnectionClose(); + } + + await server.StopAsync(); + } + + mockKestrelTrace.Verify(t => t.ResponseMinimumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>()), Times.Never()); + mockKestrelTrace.Verify(t => t.ConnectionStop(It.IsAny<string>()), Times.Once()); + Assert.False(requestAborted); + } + + [Fact] + [Flaky("https://github.com/dotnet/aspnetcore/issues/13219", FlakyOn.AzP.Linux, FlakyOn.Helix.All)] + public async Task ClientCanReceiveFullConnectionCloseResponseWithoutErrorAtALowDataRate() + { + var chunkSize = 64 * 128 * 1024; + var chunkCount = 4; + var chunkData = new byte[chunkSize]; + + var requestAborted = false; + var appFuncCompleted = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); + var mockKestrelTrace = new Mock<IKestrelTrace>(); + + var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) + { + ServerOptions = + { + Limits = + { + MinResponseDataRate = new MinDataRate(bytesPerSecond: 240, gracePeriod: TimeSpan.FromSeconds(2)) + } + } + }; + + testContext.InitializeHeartbeat(); + var dateHeaderValueManager = new DateHeaderValueManager(); + dateHeaderValueManager.OnHeartbeat(DateTimeOffset.MinValue); + testContext.DateHeaderValueManager = dateHeaderValueManager; var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); @@ -785,11 +957,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests "", ""); - var minTotalOutputSize = chunkCount * chunkSize; + await connection.Receive( + "HTTP/1.1 200 OK", + "Connection: close", + $"Date: {dateHeaderValueManager.GetDateHeaderValues().String}"); // Make sure consuming a single chunk exceeds the 2 second timeout. var targetBytesPerSecond = chunkSize / 4; - await AssertStreamCompleted(connection.Stream, minTotalOutputSize, targetBytesPerSecond); + + // expectedBytes was determined by manual testing. A constant Date header is used, so this shouldn't change unless + // the response header writing logic or response body chunking logic itself changes. + await AssertStreamCompletedAtTargetRate(connection.Stream, expectedBytes: 33_553_556, targetBytesPerSecond); await appFuncCompleted.Task.DefaultTimeout(); } await server.StopAsync(); @@ -800,87 +978,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests Assert.False(requestAborted); } - private bool ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseHeadersRetryPredicate(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"); - - [Fact] - [Flaky("https://github.com/dotnet/corefx/issues/30691", FlakyOn.AzP.Windows)] - [CollectDump] - public async Task ConnectionNotClosedWhenClientSatisfiesMinimumDataRateGivenLargeResponseHeaders() - { - var headerSize = 1024 * 1024; // 1 MB for each header value - var headerCount = 64; // 64 MB of headers per response - var requestCount = 4; // Minimum of 256 MB of total response headers - var headerValue = new string('a', headerSize); - var headerStringValues = new StringValues(Enumerable.Repeat(headerValue, headerCount).ToArray()); - - var requestAborted = false; - var mockKestrelTrace = new Mock<IKestrelTrace>(); - - var testContext = new TestServiceContext(LoggerFactory, mockKestrelTrace.Object) - { - ServerOptions = - { - Limits = - { - MinResponseDataRate = new MinDataRate(bytesPerSecond: 240, gracePeriod: TimeSpan.FromSeconds(2)) - } - } - }; - - testContext.InitializeHeartbeat(); - - var listenOptions = new ListenOptions(new IPEndPoint(IPAddress.Loopback, 0)); - - async Task App(HttpContext context) - { - context.RequestAborted.Register(() => - { - requestAborted = true; - }); - - context.Response.Headers[$"X-Custom-Header"] = headerStringValues; - context.Response.ContentLength = 0; - - await context.Response.BodyWriter.FlushAsync(); - } - - using (var server = new TestServer(App, testContext, listenOptions)) - { - using (var connection = server.CreateConnection()) - { - for (var i = 0; i < requestCount - 1; i++) - { - await connection.Send( - "GET / HTTP/1.1", - "Host:", - "", - ""); - } - - // Close the connection with the last request so AssertStreamCompleted actually completes. - await connection.Send( - "GET / HTTP/1.1", - "Host:", - "Connection: close", - "", - ""); - - var responseSize = headerSize * headerCount; - var minTotalOutputSize = requestCount * responseSize; - - // Make sure consuming a single set of response headers exceeds the 2 second timeout. - var targetBytesPerSecond = responseSize / 4; - await AssertStreamCompleted(connection.Stream, minTotalOutputSize, targetBytesPerSecond); - } - await server.StopAsync(); - } - - mockKestrelTrace.Verify(t => t.ResponseMinimumDataRateNotSatisfied(It.IsAny<string>(), It.IsAny<string>()), Times.Never()); - mockKestrelTrace.Verify(t => t.ConnectionStop(It.IsAny<string>()), Times.Once()); - Assert.False(requestAborted); - } - private async Task AssertStreamAborted(Stream stream, int totalBytes) { var receiveBuffer = new byte[64 * 1024]; @@ -908,7 +1005,30 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests Assert.True(totalReceived < totalBytes, $"{nameof(AssertStreamAborted)} Stream completed successfully."); } - private async Task AssertStreamCompleted(Stream stream, long minimumBytes, int targetBytesPerSecond) + private async Task AssertBytesReceivedAtTargetRate(Stream stream, int expectedBytes, int targetBytesPerSecond) + { + var receiveBuffer = new byte[64 * 1024]; + var totalReceived = 0; + var startTime = DateTimeOffset.UtcNow; + + do + { + var received = await stream.ReadAsync(receiveBuffer, 0, Math.Min(receiveBuffer.Length, expectedBytes - totalReceived)); + + Assert.NotEqual(0, received); + + totalReceived += received; + + var expectedTimeElapsed = TimeSpan.FromSeconds(totalReceived / targetBytesPerSecond); + var timeElapsed = DateTimeOffset.UtcNow - startTime; + if (timeElapsed < expectedTimeElapsed) + { + await Task.Delay(expectedTimeElapsed - timeElapsed); + } + } while (totalReceived < expectedBytes); + } + + private async Task AssertStreamCompletedAtTargetRate(Stream stream, long expectedBytes, int targetBytesPerSecond) { var receiveBuffer = new byte[64 * 1024]; var received = 0; @@ -928,7 +1048,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } } while (received > 0); - Assert.True(totalReceived >= minimumBytes, $"{nameof(AssertStreamCompleted)} Stream aborted prematurely."); + Assert.Equal(expectedBytes, totalReceived); } public static TheoryData<string, StringValues, string> NullHeaderData diff --git a/src/Servers/Kestrel/test/FunctionalTests/UnixDomainSocketsTests.cs b/src/Servers/Kestrel/test/FunctionalTests/UnixDomainSocketsTests.cs index 12fe59d9e8..a6a49d8b3b 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/UnixDomainSocketsTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/UnixDomainSocketsTests.cs @@ -12,6 +12,8 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections.Features; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; @@ -96,7 +98,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests var read = 0; while (read < data.Length) { - read += await socket.ReceiveAsync(buffer.AsMemory(read, buffer.Length - read), SocketFlags.None).DefaultTimeout(); + var bytesReceived = await socket.ReceiveAsync(buffer.AsMemory(read, buffer.Length - read), SocketFlags.None).DefaultTimeout(); + read += bytesReceived; + if (bytesReceived <= 0) break; } Assert.Equal(data, buffer); @@ -114,6 +118,73 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } } +#if LIBUV + [OSSkipCondition(OperatingSystems.Windows, SkipReason = "Libuv does not support unix domain sockets on Windows.")] +#else + [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_RS4)] +#endif + [ConditionalFact] + [CollectDump] + public async Task TestUnixDomainSocketWithUrl() + { + var path = Path.GetTempFileName(); + var url = $"http://unix:/{path}"; + + Delete(path); + + try + { + var hostBuilder = TransportSelector.GetWebHostBuilder() + .UseUrls(url) + .UseKestrel() + .ConfigureServices(AddTestLogging) + .Configure(app => + { + app.Run(async context => + { + await context.Response.WriteAsync("Hello World"); + }); + }); + + using (var host = hostBuilder.Build()) + { + await host.StartAsync().DefaultTimeout(); + + // https://github.com/dotnet/corefx/issues/5999 + // .NET Core HttpClient does not support unix sockets, it's difficult to parse raw response data. below is a little hacky way. + using (var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified)) + { + await socket.ConnectAsync(new UnixDomainSocketEndPoint(path)).DefaultTimeout(); + + var httpRequest = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"); + await socket.SendAsync(httpRequest, SocketFlags.None).DefaultTimeout(); + + var readBuffer = new byte[512]; + var read = 0; + while (true) + { + var bytesReceived = await socket.ReceiveAsync(readBuffer.AsMemory(read), SocketFlags.None).DefaultTimeout(); + read += bytesReceived; + if (bytesReceived <= 0) break; + } + + var httpResponse = Encoding.ASCII.GetString(readBuffer, 0, read); + int httpStatusStart = httpResponse.IndexOf(' ') + 1; + int httpStatusEnd = httpResponse.IndexOf(' ', httpStatusStart); + + var httpStatus = int.Parse(httpResponse.Substring(httpStatusStart, httpStatusEnd - httpStatusStart)); + Assert.Equal(httpStatus, StatusCodes.Status200OK); + + } + await host.StopAsync().DefaultTimeout(); + } + } + finally + { + Delete(path); + } + } + private static void Delete(string path) { try diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs index a294d65225..9814918386 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs @@ -6,13 +6,14 @@ using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Http; +using System.Net.Http.HPack; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Server.Kestrel.Core.Features; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; @@ -954,7 +955,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public async Task Frame_MultipleStreams_RequestsNotFinished_EnhanceYourCalm() { _serviceContext.ServerOptions.Limits.Http2.MaxStreamsPerConnection = 1; - var tcs = new TaskCompletionSource<object>(); + var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); await InitializeConnectionAsync(async context => { await tcs.Task.DefaultTimeout(); @@ -1564,7 +1565,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests ignoreNonGoAwayFrames: false, expectedLastStreamId: 1, expectedErrorCode: Http2ErrorCode.COMPRESSION_ERROR, - expectedErrorMessage: CoreStrings.HPackErrorIncompleteHeaderBlock); + expectedErrorMessage: SR.net_http_hpack_incomplete_header_block); } [Fact] @@ -1592,7 +1593,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests ignoreNonGoAwayFrames: false, expectedLastStreamId: 1, expectedErrorCode: Http2ErrorCode.COMPRESSION_ERROR, - expectedErrorMessage: CoreStrings.HPackErrorIntegerTooBig); + expectedErrorMessage: SR.net_http_hpack_bad_integer); } [Theory] @@ -1718,14 +1719,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { await InitializeConnectionAsync(_noopApplication); - await SendHeadersAsync(1, Http2HeadersFrameFlags.END_HEADERS, headers); + await SendHeadersAsync(1, Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM, headers); await WaitForStreamErrorAsync( expectedStreamId: 1, expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, expectedErrorMessage: CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields); // Verify that the stream ID can't be re-used - await SendHeadersAsync(1, Http2HeadersFrameFlags.END_HEADERS, _browserRequestHeaders); + await SendHeadersAsync(1, Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM, _browserRequestHeaders); await WaitForConnectionErrorAsync<Http2ConnectionErrorException>( ignoreNonGoAwayFrames: false, expectedLastStreamId: 1, @@ -3431,7 +3432,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests ignoreNonGoAwayFrames: false, expectedLastStreamId: 1, expectedErrorCode: Http2ErrorCode.COMPRESSION_ERROR, - expectedErrorMessage: CoreStrings.HPackErrorIncompleteHeaderBlock); + expectedErrorMessage: SR.net_http_hpack_incomplete_header_block); } [Theory] @@ -3457,7 +3458,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { await InitializeConnectionAsync(_noopApplication); - Assert.True(await SendHeadersAsync(1, Http2HeadersFrameFlags.NONE, headers)); + Assert.True(await SendHeadersAsync(1, Http2HeadersFrameFlags.END_STREAM, headers)); await SendEmptyContinuationFrameAsync(1, Http2ContinuationFrameFlags.END_HEADERS); await WaitForStreamErrorAsync( @@ -3466,7 +3467,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests expectedErrorMessage: CoreStrings.Http2ErrorMissingMandatoryPseudoHeaderFields); // Verify that the stream ID can't be re-used - await SendHeadersAsync(1, Http2HeadersFrameFlags.END_HEADERS, headers); + await SendHeadersAsync(1, Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM, headers); await WaitForConnectionErrorAsync<Http2ConnectionErrorException>( ignoreNonGoAwayFrames: false, expectedLastStreamId: 1, @@ -3964,6 +3965,160 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); } + [Theory] + [InlineData((int)(Http2FrameType.DATA))] + [InlineData((int)(Http2FrameType.WINDOW_UPDATE))] + [InlineData((int)(Http2FrameType.HEADERS))] + [InlineData((int)(Http2FrameType.CONTINUATION))] + public async Task RefusedStream_Post_ResetsAndDrainsRequest(int intFinalFrameType) + { + var finalFrameType = (Http2FrameType)intFinalFrameType; + + CreateConnection(); + + _connection.ServerSettings.MaxConcurrentStreams = 0; // Refuse all streams + + var connectionTask = _connection.ProcessRequestsAsync(new DummyApplication(_noopApplication)); + + async Task CompletePipeOnTaskCompletion() + { + try + { + await connectionTask; + } + finally + { + _pair.Transport.Input.Complete(); + _pair.Transport.Output.Complete(); + } + } + + _connectionTask = CompletePipeOnTaskCompletion(); + + await SendPreambleAsync().ConfigureAwait(false); + await SendSettingsAsync(); + + // Requests can be sent before receiving and acking settings. + + var headers = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "POST"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "http"), + }; + + await StartStreamAsync(1, headers, endStream: false); + + await ExpectAsync(Http2FrameType.SETTINGS, + withLength: 3 * Http2FrameReader.SettingSize, + withFlags: 0, + withStreamId: 0); + + await ExpectAsync(Http2FrameType.WINDOW_UPDATE, + withLength: 4, + withFlags: 0, + withStreamId: 0); + + await ExpectAsync(Http2FrameType.SETTINGS, + withLength: 0, + withFlags: (byte)Http2SettingsFrameFlags.ACK, + withStreamId: 0); + + await WaitForStreamErrorAsync(1, Http2ErrorCode.REFUSED_STREAM, "HTTP/2 stream ID 1 error (REFUSED_STREAM): A new stream was refused because this connection has reached its stream limit."); + + // These frames should be drained and ignored while in cool-down mode. + switch (finalFrameType) + { + case Http2FrameType.DATA: + await SendDataAsync(1, new byte[100], endStream: true); + break; + case Http2FrameType.WINDOW_UPDATE: + await SendWindowUpdateAsync(1, 1024); + break; + case Http2FrameType.HEADERS: + await SendHeadersAsync(1, Http2HeadersFrameFlags.END_STREAM | Http2HeadersFrameFlags.END_HEADERS, _requestTrailers); + break; + case Http2FrameType.CONTINUATION: + await SendHeadersAsync(1, Http2HeadersFrameFlags.END_STREAM, _requestTrailers); + await SendContinuationAsync(1, Http2ContinuationFrameFlags.END_HEADERS, _requestTrailers); + break; + default: + throw new NotImplementedException(finalFrameType.ToString()); + } + + await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + } + + [Fact] + public async Task RefusedStream_Post_2xLimitRefused() + { + var requestBlock = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + + CreateConnection(); + + _connection.ServerSettings.MaxConcurrentStreams = 1; + + var connectionTask = _connection.ProcessRequestsAsync(new DummyApplication(_ => requestBlock.Task)); + + async Task CompletePipeOnTaskCompletion() + { + try + { + await connectionTask; + } + finally + { + _pair.Transport.Input.Complete(); + _pair.Transport.Output.Complete(); + } + } + + _connectionTask = CompletePipeOnTaskCompletion(); + + await SendPreambleAsync().ConfigureAwait(false); + await SendSettingsAsync(); + + // Requests can be sent before receiving and acking settings. + + var headers = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "POST"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "http"), + }; + + // This mimics gRPC, sending headers and data close together before receiving a reset. + await StartStreamAsync(1, headers, endStream: false); + await SendDataAsync(1, new byte[100], endStream: false); + await StartStreamAsync(3, headers, endStream: false); + await SendDataAsync(3, new byte[100], endStream: false); + await StartStreamAsync(5, headers, endStream: false); + await SendDataAsync(5, new byte[100], endStream: false); + await StartStreamAsync(7, headers, endStream: false); + await SendDataAsync(7, new byte[100], endStream: false); + + await ExpectAsync(Http2FrameType.SETTINGS, + withLength: 3 * Http2FrameReader.SettingSize, + withFlags: 0, + withStreamId: 0); + + await ExpectAsync(Http2FrameType.WINDOW_UPDATE, + withLength: 4, + withFlags: 0, + withStreamId: 0); + + await ExpectAsync(Http2FrameType.SETTINGS, + withLength: 0, + withFlags: (byte)Http2SettingsFrameFlags.ACK, + withStreamId: 0); + + await WaitForStreamErrorAsync(3, Http2ErrorCode.REFUSED_STREAM, "HTTP/2 stream ID 3 error (REFUSED_STREAM): A new stream was refused because this connection has reached its stream limit."); + await WaitForStreamErrorAsync(5, Http2ErrorCode.REFUSED_STREAM, "HTTP/2 stream ID 5 error (REFUSED_STREAM): A new stream was refused because this connection has reached its stream limit."); + await WaitForStreamErrorAsync(7, Http2ErrorCode.REFUSED_STREAM, "HTTP/2 stream ID 7 error (REFUSED_STREAM): A new stream was refused because this connection has reached its stream limit."); + requestBlock.SetResult(0); + await StopConnectionAsync(expectedLastStreamId: 7, ignoreNonGoAwayFrames: true); + } + [Theory] [InlineData((int)(Http2FrameType.DATA))] [InlineData((int)(Http2FrameType.HEADERS))] diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs index 4937000db9..ea2c0d4ce8 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs @@ -6,6 +6,8 @@ using System.Buffers; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Http; +using System.Net.Http.HPack; using System.Runtime.ExceptionServices; using System.Text; using System.Threading; @@ -15,7 +17,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Server.Kestrel.Core.Features; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; @@ -996,7 +997,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal("0", _decodedHeaders[HeaderNames.ContentLength]); } - [Fact] // TODO https://github.com/aspnet/AspNetCore/issues/7034 + [Fact] // TODO https://github.com/dotnet/aspnetcore/issues/7034 public async Task ContentLength_Response_FirstWriteMoreBytesWritten_Throws_Sends500() { var headers = new[] @@ -2041,7 +2042,128 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await _connectionTask; var message = Assert.Single(TestApplicationErrorLogger.Messages, m => m.Exception is HPackEncodingException); - Assert.Contains(CoreStrings.HPackErrorNotEnoughBuffer, message.Exception.Message); + Assert.Contains(SR.net_http_hpack_encode_failure, message.Exception.Message); + } + + [Fact] + public async Task ResponseTrailers_WithLargeUnflushedData_DataExceedsFlowControlAvailableAndNotSentWithTrailers() + { + const int windowSize = (int)Http2PeerSettings.DefaultMaxFrameSize; + _clientSettings.InitialWindowSize = windowSize; + + var headers = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "GET"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "http"), + }; + await InitializeConnectionAsync(async context => + { + await context.Response.StartAsync(); + + // Body exceeds flow control available and requires the client to allow more + // data via updating the window + context.Response.BodyWriter.GetMemory(windowSize + 1); + context.Response.BodyWriter.Advance(windowSize + 1); + + context.Response.AppendTrailer("CustomName", "Custom Value"); + }).DefaultTimeout(); + + await StartStreamAsync(1, headers, endStream: true).DefaultTimeout(); + + var headersFrame = await ExpectAsync(Http2FrameType.HEADERS, + withLength: 37, + withFlags: (byte)Http2HeadersFrameFlags.END_HEADERS, + withStreamId: 1).DefaultTimeout(); + + await ExpectAsync(Http2FrameType.DATA, + withLength: 16384, + withFlags: (byte)Http2DataFrameFlags.NONE, + withStreamId: 1).DefaultTimeout(); + + var dataTask = ExpectAsync(Http2FrameType.DATA, + withLength: 1, + withFlags: (byte)Http2DataFrameFlags.NONE, + withStreamId: 1).DefaultTimeout(); + + // Reading final frame of data requires window update + // Verify this data task is waiting on window update + Assert.False(dataTask.IsCompletedSuccessfully); + + await SendWindowUpdateAsync(1, 1); + + await dataTask; + + var trailersFrame = await ExpectAsync(Http2FrameType.HEADERS, + withLength: 25, + withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), + withStreamId: 1).DefaultTimeout(); + + await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false).DefaultTimeout(); + + _hpackDecoder.Decode(headersFrame.PayloadSequence, endHeaders: false, handler: this); + + Assert.Equal(2, _decodedHeaders.Count); + Assert.Contains("date", _decodedHeaders.Keys, StringComparer.OrdinalIgnoreCase); + Assert.Equal("200", _decodedHeaders[HeaderNames.Status]); + + _decodedHeaders.Clear(); + _hpackDecoder.Decode(trailersFrame.PayloadSequence, endHeaders: true, handler: this); + + Assert.Single(_decodedHeaders); + Assert.Equal("Custom Value", _decodedHeaders["CustomName"]); + } + + [Fact] + public async Task ResponseTrailers_WithUnflushedData_DataSentWithTrailers() + { + var headers = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "GET"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "http"), + }; + await InitializeConnectionAsync(async context => + { + await context.Response.StartAsync(); + + var s = context.Response.BodyWriter.GetMemory(1); + s.Span[0] = byte.MaxValue; + context.Response.BodyWriter.Advance(1); + + context.Response.AppendTrailer("CustomName", "Custom Value"); + }); + + await StartStreamAsync(1, headers, endStream: true); + + var headersFrame = await ExpectAsync(Http2FrameType.HEADERS, + withLength: 37, + withFlags: (byte)Http2HeadersFrameFlags.END_HEADERS, + withStreamId: 1); + + await ExpectAsync(Http2FrameType.DATA, + withLength: 1, + withFlags: (byte)Http2DataFrameFlags.NONE, + withStreamId: 1); + + var trailersFrame = await ExpectAsync(Http2FrameType.HEADERS, + withLength: 25, + withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), + withStreamId: 1); + + await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + + _hpackDecoder.Decode(headersFrame.PayloadSequence, endHeaders: false, handler: this); + + Assert.Equal(2, _decodedHeaders.Count); + Assert.Contains("date", _decodedHeaders.Keys, StringComparer.OrdinalIgnoreCase); + Assert.Equal("200", _decodedHeaders[HeaderNames.Status]); + + _decodedHeaders.Clear(); + _hpackDecoder.Decode(trailersFrame.PayloadSequence, endHeaders: true, handler: this); + + Assert.Single(_decodedHeaders); + Assert.Equal("Custom Value", _decodedHeaders["CustomName"]); } [Fact] @@ -2493,7 +2615,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await StartStreamAsync(1, _browserRequestHeaders, endStream: true); var message = await appFinished.Task.DefaultTimeout(); - Assert.Equal(CoreStrings.HPackErrorNotEnoughBuffer, message); + Assert.Equal(SR.net_http_hpack_encode_failure, message); // Just the StatusCode gets written before aborting in the continuation frame await ExpectAsync(Http2FrameType.HEADERS, @@ -2504,7 +2626,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _pair.Application.Output.Complete(); await WaitForConnectionErrorAsync<HPackEncodingException>(ignoreNonGoAwayFrames: false, expectedLastStreamId: int.MaxValue, Http2ErrorCode.INTERNAL_ERROR, - CoreStrings.HPackErrorNotEnoughBuffer); + SR.net_http_hpack_encode_failure); } [Fact] diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs index 5b875bffab..556e62a07f 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs @@ -9,6 +9,8 @@ using System.Collections.Generic; using System.IO; using System.IO.Pipelines; using System.Linq; +using System.Net.Http; +using System.Net.Http.HPack; using System.Reflection; using System.Text; using System.Threading; @@ -21,7 +23,6 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Logging; @@ -400,12 +401,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests base.Dispose(); } - void IHttpHeadersHandler.OnHeader(Span<byte> name, Span<byte> value) + void IHttpHeadersHandler.OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { _decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiOrUTF8StringNonNullCharacters(); } - void IHttpHeadersHandler.OnHeadersComplete() { } + void IHttpHeadersHandler.OnHeadersComplete(bool endStream) { } protected void CreateConnection() { @@ -687,7 +688,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests await writableBuffer.FlushAsync().AsTask().DefaultTimeout(); } - protected Task SendPreambleAsync() => SendAsync(new ArraySegment<byte>(Http2Connection.ClientPreface)); + protected Task SendPreambleAsync() => SendAsync(Http2Connection.ClientPreface); protected async Task SendSettingsAsync() { @@ -1112,12 +1113,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var buffer = result.Buffer; var consumed = buffer.Start; var examined = buffer.Start; + var copyBuffer = buffer; try { Assert.True(buffer.Length > 0); - if (Http2FrameReader.ReadFrame(buffer, frame, maxFrameSize, out var framePayload)) + if (Http2FrameReader.TryReadFrame(ref buffer, frame, maxFrameSize, out var framePayload)) { consumed = examined = framePayload.End; frame.Payload = framePayload.ToArray(); @@ -1135,7 +1137,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests } finally { - _bytesReceived += buffer.Slice(buffer.Start, consumed).Length; + _bytesReceived += copyBuffer.Slice(copyBuffer.Start, consumed).Length; _pair.Application.Input.AdvanceTo(consumed, examined); } } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/TlsTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/TlsTests.cs index f52e83eb62..950a304ecb 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/TlsTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/TlsTests.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.Http2 private static X509Certificate2 _x509Certificate2 = TestResources.GetTestCertificate(); [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/7000")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/7000")] public async Task TlsHandshakeRejectsTlsLessThan12() { using (var server = new TestServer(context => @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.Http2 try { - if (Http2FrameReader.ReadFrame(buffer, frame, 16_384, out var framePayload)) + if (Http2FrameReader.TryReadFrame(ref buffer, frame, 16_384, out var framePayload)) { consumed = examined = framePayload.End; return frame; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs new file mode 100644 index 0000000000..d56624e4f9 --- /dev/null +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Net.Http.Headers; +using Xunit; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests +{ + public class Http3StreamTests : Http3TestBase + { + [Fact] + public async Task HelloWorldTest() + { + var headers = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "Custom"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "http"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"), + }; + + var requestStream = await InitializeConnectionAndStreamsAsync(_echoApplication); + + var doneWithHeaders = await requestStream.SendHeadersAsync(headers); + await requestStream.SendDataAsync(Encoding.ASCII.GetBytes("Hello world")); + + var responseHeaders = await requestStream.ExpectHeadersAsync(); + var responseData = await requestStream.ExpectDataAsync(); + Assert.Equal("Hello world", Encoding.ASCII.GetString(responseData.ToArray())); + } + } +} diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3TestBase.cs new file mode 100644 index 0000000000..aab3b504d9 --- /dev/null +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3TestBase.cs @@ -0,0 +1,386 @@ +using System; +using System.Buffers; +using System.Collections.Generic; +using System.IO; +using System.IO.Pipelines; +using System.Net.Http; +using System.Reflection; +using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Abstractions.Features; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http3.QPack; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; +using Microsoft.AspNetCore.Testing; +using Moq; +using Xunit; +using Xunit.Abstractions; +using static Microsoft.AspNetCore.Server.Kestrel.Core.Tests.Http2TestBase; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests +{ + public class Http3TestBase : TestApplicationErrorLoggerLoggedTest, IDisposable, IQuicCreateStreamFeature, IQuicStreamListenerFeature + { + internal TestServiceContext _serviceContext; + internal Http3Connection _connection; + internal readonly TimeoutControl _timeoutControl; + internal readonly Mock<IKestrelTrace> _mockKestrelTrace = new Mock<IKestrelTrace>(); + protected readonly Mock<ConnectionContext> _mockConnectionContext = new Mock<ConnectionContext>(); + internal readonly Mock<ITimeoutHandler> _mockTimeoutHandler = new Mock<ITimeoutHandler>(); + internal readonly Mock<MockTimeoutControlBase> _mockTimeoutControl; + internal readonly MemoryPool<byte> _memoryPool = SlabMemoryPoolFactory.Create(); + protected Task _connectionTask; + protected readonly RequestDelegate _echoApplication; + + private readonly Channel<ConnectionContext> _acceptConnectionQueue = Channel.CreateUnbounded<ConnectionContext>(new UnboundedChannelOptions + { + SingleReader = true, + SingleWriter = true + }); + + public Http3TestBase() + { + _timeoutControl = new TimeoutControl(_mockTimeoutHandler.Object); + _mockTimeoutControl = new Mock<MockTimeoutControlBase>(_timeoutControl) { CallBase = true }; + _timeoutControl.Debugger = Mock.Of<IDebugger>(); + _echoApplication = async context => + { + var buffer = new byte[Http3PeerSettings.MinAllowedMaxFrameSize]; + var received = 0; + + while ((received = await context.Request.Body.ReadAsync(buffer, 0, buffer.Length)) > 0) + { + await context.Response.Body.WriteAsync(buffer, 0, received); + } + }; + } + + public override void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) + { + base.Initialize(context, methodInfo, testMethodArguments, testOutputHelper); + + _serviceContext = new TestServiceContext(LoggerFactory, _mockKestrelTrace.Object) + { + Scheduler = PipeScheduler.Inline, + }; + } + + protected async Task InitializeConnectionAsync(RequestDelegate application) + { + if (_connection == null) + { + CreateConnection(); + } + + _connectionTask = _connection.ProcessRequestsAsync(new DummyApplication(application)); + + await Task.CompletedTask; + } + + internal async ValueTask<Http3RequestStream> InitializeConnectionAndStreamsAsync(RequestDelegate application) + { + await InitializeConnectionAsync(application); + + var controlStream1 = await CreateControlStream(0); + var controlStream2 = await CreateControlStream(2); + var controlStream3 = await CreateControlStream(3); + + return await CreateRequestStream(); + } + + protected void CreateConnection() + { + var limits = _serviceContext.ServerOptions.Limits; + + var features = new FeatureCollection(); + features.Set<IQuicCreateStreamFeature>(this); + features.Set<IQuicStreamListenerFeature>(this); + + var httpConnectionContext = new HttpConnectionContext + { + ConnectionContext = _mockConnectionContext.Object, + ConnectionFeatures = features, + ServiceContext = _serviceContext, + MemoryPool = _memoryPool, + Transport = null, // Make sure it's null + TimeoutControl = _mockTimeoutControl.Object + }; + + _connection = new Http3Connection(httpConnectionContext); + var httpConnection = new HttpConnection(httpConnectionContext); + httpConnection.Initialize(_connection); + _mockTimeoutHandler.Setup(h => h.OnTimeout(It.IsAny<TimeoutReason>())) + .Callback<TimeoutReason>(r => httpConnection.OnTimeout(r)); + } + + private static PipeOptions GetInputPipeOptions(ServiceContext serviceContext, MemoryPool<byte> memoryPool, PipeScheduler writerScheduler) => new PipeOptions + ( + pool: memoryPool, + readerScheduler: serviceContext.Scheduler, + writerScheduler: writerScheduler, + pauseWriterThreshold: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0, + resumeWriterThreshold: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0, + useSynchronizationContext: false, + minimumSegmentSize: memoryPool.GetMinimumSegmentSize() + ); + + private static PipeOptions GetOutputPipeOptions(ServiceContext serviceContext, MemoryPool<byte> memoryPool, PipeScheduler readerScheduler) => new PipeOptions + ( + pool: memoryPool, + readerScheduler: readerScheduler, + writerScheduler: serviceContext.Scheduler, + pauseWriterThreshold: GetOutputResponseBufferSize(serviceContext), + resumeWriterThreshold: GetOutputResponseBufferSize(serviceContext), + useSynchronizationContext: false, + minimumSegmentSize: memoryPool.GetMinimumSegmentSize() + ); + + private static long GetOutputResponseBufferSize(ServiceContext serviceContext) + { + var bufferSize = serviceContext.ServerOptions.Limits.MaxResponseBufferSize; + if (bufferSize == 0) + { + // 0 = no buffering so we need to configure the pipe so the writer waits on the reader directly + return 1; + } + + // null means that we have no back pressure + return bufferSize ?? 0; + } + + public ValueTask<ConnectionContext> StartUnidirectionalStreamAsync() + { + var stream = new Http3ControlStream(this, _connection); + // TODO put these somewhere to be read. + return new ValueTask<ConnectionContext>(stream.ConnectionContext); + } + + public async ValueTask<ConnectionContext> AcceptAsync() + { + while (await _acceptConnectionQueue.Reader.WaitToReadAsync()) + { + while (_acceptConnectionQueue.Reader.TryRead(out var connection)) + { + return connection; + } + } + + return null; + } + + internal async ValueTask<Http3ControlStream> CreateControlStream(int id) + { + var stream = new Http3ControlStream(this, _connection); + _acceptConnectionQueue.Writer.TryWrite(stream.ConnectionContext); + await stream.WriteStreamIdAsync(id); + return stream; + } + + internal ValueTask<Http3RequestStream> CreateRequestStream() + { + var stream = new Http3RequestStream(this, _connection); + _acceptConnectionQueue.Writer.TryWrite(stream.ConnectionContext); + return new ValueTask<Http3RequestStream>(stream); + } + + public ValueTask<ConnectionContext> StartBidirectionalStreamAsync() + { + var stream = new Http3RequestStream(this, _connection); + // TODO put these somewhere to be read. + return new ValueTask<ConnectionContext>(stream.ConnectionContext); + } + + internal class Http3StreamBase + { + protected DuplexPipe.DuplexPipePair _pair; + protected Http3TestBase _testBase; + protected Http3Connection _connection; + + protected Task SendAsync(ReadOnlySpan<byte> span) + { + var writableBuffer = _pair.Application.Output; + writableBuffer.Write(span); + return FlushAsync(writableBuffer); + } + + protected static async Task FlushAsync(PipeWriter writableBuffer) + { + await writableBuffer.FlushAsync().AsTask().DefaultTimeout(); + } + } + + internal class Http3RequestStream : Http3StreamBase, IHttpHeadersHandler, IQuicStreamFeature + { + internal ConnectionContext ConnectionContext { get; } + + public bool IsUnidirectional => false; + + public long StreamId => 0; + + private readonly byte[] _headerEncodingBuffer = new byte[Http3PeerSettings.MinAllowedMaxFrameSize]; + private QPackEncoder _qpackEncoder = new QPackEncoder(); + private QPackDecoder _qpackDecoder = new QPackDecoder(10000, 10000); + private long _bytesReceived; + protected readonly Dictionary<string, string> _decodedHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + + public Http3RequestStream(Http3TestBase testBase, Http3Connection connection) + { + _testBase = testBase; + _connection = connection; + var inputPipeOptions = GetInputPipeOptions(_testBase._serviceContext, _testBase._memoryPool, PipeScheduler.ThreadPool); + var outputPipeOptions = GetOutputPipeOptions(_testBase._serviceContext, _testBase._memoryPool, PipeScheduler.ThreadPool); + + _pair = DuplexPipe.CreateConnectionPair(inputPipeOptions, outputPipeOptions); + + ConnectionContext = new DefaultConnectionContext(); + ConnectionContext.Transport = _pair.Transport; + ConnectionContext.Features.Set<IQuicStreamFeature>(this); + } + + public async Task<bool> SendHeadersAsync(IEnumerable<KeyValuePair<string, string>> headers) + { + var outputWriter = _pair.Application.Output; + var frame = new Http3Frame(); + frame.PrepareHeaders(); + var buffer = _headerEncodingBuffer.AsMemory(); + var done = _qpackEncoder.BeginEncode(headers, buffer.Span, out var length); + frame.Length = length; + // TODO may want to modify behavior of input frames to mock different client behavior (client can send anything). + Http3FrameWriter.WriteHeader(frame, outputWriter); + await SendAsync(buffer.Span.Slice(0, length)); + return done; + } + + internal async Task SendDataAsync(Memory<byte> data) + { + var outputWriter = _pair.Application.Output; + var frame = new Http3Frame(); + frame.PrepareData(); + frame.Length = data.Length; + Http3FrameWriter.WriteHeader(frame, outputWriter); + await SendAsync(data.Span); + } + + internal async Task<IEnumerable<KeyValuePair<string, string>>> ExpectHeadersAsync() + { + var http3WithPayload = await ReceiveFrameAsync(); + _qpackDecoder.Decode(http3WithPayload.PayloadSequence, this); + return _decodedHeaders; + } + + internal async Task<Memory<byte>> ExpectDataAsync() + { + var http3WithPayload = await ReceiveFrameAsync(); + return http3WithPayload.Payload; + } + + internal async Task<Http3FrameWithPayload> ReceiveFrameAsync(uint maxFrameSize = Http3PeerSettings.DefaultMaxFrameSize) + { + var frame = new Http3FrameWithPayload(); + + while (true) + { + var result = await _pair.Application.Input.ReadAsync().AsTask().DefaultTimeout(); + var buffer = result.Buffer; + var consumed = buffer.Start; + var examined = buffer.Start; + var copyBuffer = buffer; + + try + { + Assert.True(buffer.Length > 0); + + if (Http3FrameReader.TryReadFrame(ref buffer, frame, maxFrameSize, out var framePayload)) + { + consumed = examined = framePayload.End; + frame.Payload = framePayload.ToArray(); + return frame; + } + else + { + examined = buffer.End; + } + + if (result.IsCompleted) + { + throw new IOException("The reader completed without returning a frame."); + } + } + finally + { + _bytesReceived += copyBuffer.Slice(copyBuffer.Start, consumed).Length; + _pair.Application.Input.AdvanceTo(consumed, examined); + } + } + } + + public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) + { + _decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiOrUTF8StringNonNullCharacters(); + } + + public void OnHeadersComplete(bool endHeaders) + { + } + } + + internal class Http3FrameWithPayload : Http3Frame + { + public Http3FrameWithPayload() : base() + { + } + + // This does not contain extended headers + public Memory<byte> Payload { get; set; } + + public ReadOnlySequence<byte> PayloadSequence => new ReadOnlySequence<byte>(Payload); + } + + + internal class Http3ControlStream : Http3StreamBase, IQuicStreamFeature + { + internal ConnectionContext ConnectionContext { get; } + + public bool IsUnidirectional => true; + + // TODO + public long StreamId => 0; + + public Http3ControlStream(Http3TestBase testBase, Http3Connection connection) + { + _testBase = testBase; + _connection = connection; + var inputPipeOptions = GetInputPipeOptions(_testBase._serviceContext, _testBase._memoryPool, PipeScheduler.ThreadPool); + var outputPipeOptions = GetOutputPipeOptions(_testBase._serviceContext, _testBase._memoryPool, PipeScheduler.ThreadPool); + + _pair = DuplexPipe.CreateConnectionPair(inputPipeOptions, outputPipeOptions); + + ConnectionContext = new DefaultConnectionContext(); + ConnectionContext.Transport = _pair.Transport; + ConnectionContext.Features.Set<IQuicStreamFeature>(this); + } + + public async Task WriteStreamIdAsync(int id) + { + var writableBuffer = _pair.Application.Output; + + void WriteSpan(PipeWriter pw) + { + var buffer = pw.GetSpan(sizeHint: 8); + var lengthWritten = VariableLengthIntegerHelper.WriteInteger(buffer, id); + pw.Advance(lengthWritten); + } + + WriteSpan(writableBuffer); + + await FlushAsync(writableBuffer); + } + } + } +} diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs index 45e21934be..88ee3f5c7a 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/HttpsConnectionMiddlewareTests.cs @@ -594,7 +594,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests [InlineData(HttpProtocols.Http2)] [InlineData(HttpProtocols.Http1AndHttp2)] [OSSkipCondition(OperatingSystems.MacOSX, SkipReason = "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492")] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/10428", Queues = "Debian.8.Amd64.Open")] // Debian 8 uses OpenSSL 1.0.1 which does not support HTTP/2 [MinimumOSVersion(OperatingSystems.Windows, WindowsVersions.Win81)] public async Task ListenOptionsProtolsCanBeSetAfterUseHttps(HttpProtocols httpProtocols) { diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj b/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj index bab7248341..e77498d951 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> @@ -14,14 +14,13 @@ <Content Include="$(KestrelSharedSourceRoot)test\TestCertificates\*.pfx" LinkBase="shared\TestCertificates" CopyToOutputDirectory="PreserveNewest" /> <Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" /> <Compile Include="$(KestrelSharedSourceRoot)\CorrelationIdGenerator.cs" Link="Internal\CorrelationIdGenerator.cs" /> - <Compile Include="$(KestrelSharedSourceRoot)\DuplexPipe.cs" Link="Internal\DuplexPipe.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.cs" Link="Internal\TransportConnection.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.Generated.cs" Link="Internal\TransportConnection.Generated.cs" /> <Compile Include="$(KestrelSharedSourceRoot)\TransportConnection.FeatureCollection.cs" Link="Internal\TransportConnection.FeatureCollection.cs" /> </ItemGroup> <ItemGroup> - <Reference Include="System.Threading.Channels" /> + <Reference Include="System.Threading.Channels" /> <Reference Include="Microsoft.AspNetCore.Http.Abstractions" /> <Reference Include="Microsoft.AspNetCore.Server.Kestrel" /> <Reference Include="Microsoft.Extensions.TypeNameHelper.Sources" /> diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs index 935a722029..c40b562eba 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs @@ -2541,7 +2541,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests } [Fact] - [Flaky("https://github.com/aspnet/AspNetCore/issues/12401", FlakyOn.All)] + [Flaky("https://github.com/dotnet/aspnetcore/issues/12401", FlakyOn.All)] public async Task AppAbortViaIConnectionLifetimeFeatureIsLogged() { var testContext = new TestServiceContext(LoggerFactory); diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/TestTransport/TestServer.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/TestTransport/TestServer.cs index 1c76309881..0c8e40921d 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/TestTransport/TestServer.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/TestTransport/TestServer.cs @@ -3,11 +3,13 @@ using System; using System.Buffers; +using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Http; @@ -80,7 +82,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.InMemory.FunctionalTests.TestTrans { context.ServerOptions.ApplicationServices = sp; configureKestrel(context.ServerOptions); - return new KestrelServer(_transportFactory, context); + return new KestrelServer(new List<IConnectionListenerFactory>() { _transportFactory }, context); }); }); diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/ChromeTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/ChromeTests.cs index de82af3a98..9ca98c4815 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/ChromeTests.cs +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/ChromeTests.cs @@ -83,7 +83,7 @@ namespace Interop.FunctionalTests .ConfigureServices(AddTestLogging) .Configure(app => app.Run(async context => { - if (string.Equals(context.Request.Query["TestMethod"], "POST", StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsPost(context.Request.Query["TestMethod"])) { await context.Response.WriteAsync(_postHtml); } diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/H2SpecTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/H2SpecTests.cs index 2c5f39382d..a560fdae6a 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/H2SpecTests.cs +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/H2SpecTests.cs @@ -74,7 +74,7 @@ namespace Interop.FunctionalTests Skip = skip, }); - // https://github.com/aspnet/AspNetCore/issues/11301 We should use Skip but it's broken at the moment. + // https://github.com/dotnet/aspnetcore/issues/11301 We should use Skip but it's broken at the moment. if (supportsAlpn) { dataset.Add(new H2SpecTestCase diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpClientHttp2InteropTests.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpClientHttp2InteropTests.cs index 234c127379..1f38047f58 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpClientHttp2InteropTests.cs +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/HttpClientHttp2InteropTests.cs @@ -1,9 +1,10 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using System.Net.Http; using System.Text; @@ -41,7 +42,6 @@ namespace Interop.FunctionalTests new[] { "http" } }; - // https://github.com/aspnet/AspNetCore/issues/11301 We should use Skip but it's broken at the moment. if (Utilities.CurrentPlatformSupportsAlpn()) { list.Add(new[] { "https" }); @@ -51,7 +51,7 @@ namespace Interop.FunctionalTests } } - [ConditionalTheory] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task HelloWorld(string scheme) { @@ -72,7 +72,7 @@ namespace Interop.FunctionalTests await host.StopAsync().DefaultTimeout(); } - [ConditionalTheory] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task Echo(string scheme) { @@ -102,7 +102,7 @@ namespace Interop.FunctionalTests } // Concurrency testing - [ConditionalTheory] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task MultiplexGet(string scheme) { @@ -150,7 +150,7 @@ namespace Interop.FunctionalTests } // Concurrency testing - [ConditionalTheory] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task MultiplexEcho(string scheme) { @@ -260,7 +260,7 @@ namespace Interop.FunctionalTests } } - [ConditionalTheory] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task BidirectionalStreaming(string scheme) { @@ -318,7 +318,7 @@ namespace Interop.FunctionalTests await host.StopAsync().DefaultTimeout(); } - [ConditionalTheory(Skip = "https://github.com/dotnet/corefx/issues/39404")] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task BidirectionalStreamingMoreClientData(string scheme) { @@ -388,7 +388,7 @@ namespace Interop.FunctionalTests await ReadStreamHelloWorld(stream); Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout()); - stream.Dispose(); // https://github.com/dotnet/corefx/issues/39404 can be worked around by commenting out this Dispose + stream.Dispose(); // Send one more message after the server has finished. await streamingContent.SendAsync("Hello World").DefaultTimeout(); @@ -400,7 +400,7 @@ namespace Interop.FunctionalTests await host.StopAsync().DefaultTimeout(); } - [ConditionalTheory(Skip = "https://github.com/dotnet/corefx/issues/39404")] + [Theory] [MemberData(nameof(SupportedSchemes))] public async Task ReverseEcho(string scheme) { @@ -412,16 +412,12 @@ namespace Interop.FunctionalTests webHostBuilder.ConfigureServices(AddTestLogging) .Configure(app => app.Run(async context => { - // Prime it? - // var readTask = context.Request.BodyReader.ReadAsync(); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello World"); await context.Response.CompleteAsync().DefaultTimeout(); try { - // var readResult = await readTask; - // context.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); using var streamReader = new StreamReader(context.Request.Body); var read = await streamReader.ReadToEndAsync().DefaultTimeout(); clientEcho.SetResult(read); @@ -437,7 +433,8 @@ namespace Interop.FunctionalTests var url = host.MakeUrl(scheme); using var client = CreateClient(); - // client.DefaultRequestHeaders.ExpectContinue = true; + // The client doesn't flush the headers for requests with a body unless a continue is expected. + client.DefaultRequestHeaders.ExpectContinue = true; var streamingContent = new StreamingContent(); var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); @@ -446,15 +443,8 @@ namespace Interop.FunctionalTests Assert.Equal(HttpVersion.Version20, response.Version); // Read Hello World and echo it back to the server. - /* https://github.com/dotnet/corefx/issues/39404 var read = await response.Content.ReadAsStringAsync().DefaultTimeout(); Assert.Equal("Hello World", read); - */ - var stream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); - await ReadStreamHelloWorld(stream).DefaultTimeout(); - - Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout()); - stream.Dispose(); // https://github.com/dotnet/corefx/issues/39404 can be worked around by commenting out this Dispose await streamingContent.SendAsync("Hello World").DefaultTimeout(); streamingContent.Complete(); @@ -473,6 +463,8 @@ namespace Interop.FunctionalTests { } + public Task SendStarted => _sendStarted.Task; + public async Task SendAsync(string text) { await _sendStarted.Task; @@ -514,6 +506,1096 @@ namespace Interop.FunctionalTests length = 0; return false; } + + internal void Abort() + { + if (_sendComplete == null) + { + throw new InvalidOperationException("Sending hasn't started yet."); + } + _sendComplete.TrySetException(new Exception("Abort")); + } + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ResponseTrailersWithoutData(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + context.Response.DeclareTrailer("TestTrailer"); + context.Response.AppendTrailer("TestTrailer", "TestValue"); + return Task.CompletedTask; + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var response = await client.GetAsync(url).DefaultTimeout(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Equal("TestTrailer", response.Headers.Trailer.Single()); + // The response is buffered, we must already have the trailers. + Assert.Equal("TestValue", response.TrailingHeaders.GetValues("TestTrailer").Single()); + Assert.Equal("", await response.Content.ReadAsStringAsync()); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ResponseTrailersWithData(string scheme) + { + var headersReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + context.Response.DeclareTrailer("TestTrailer"); + await context.Response.WriteAsync("Hello "); + await headersReceived.Task.DefaultTimeout(); + await context.Response.WriteAsync("World"); + context.Response.AppendTrailer("TestTrailer", "TestValue"); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Equal("TestTrailer", response.Headers.Trailer.Single()); + // The server has not sent trailers yet. + Assert.False(response.TrailingHeaders.TryGetValues("TestTrailer", out var none)); + headersReceived.SetResult(0); + var responseBody = await response.Content.ReadAsStringAsync().DefaultTimeout(); + Assert.Equal("Hello World", responseBody); + // The response is buffered, we must already have the trailers. + Assert.Equal("TestValue", response.TrailingHeaders.GetValues("TestTrailer").Single()); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ServerReset_BeforeResponse_ClientThrows(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + context.Features.Get<IHttpResetFeature>().Reset(8); // Cancel + return Task.CompletedTask; + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var exception = await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(url)).DefaultTimeout(); + Assert.Equal("The HTTP/2 server reset the stream. HTTP/2 error code 'CANCEL' (0x8).", exception?.InnerException?.InnerException.Message); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ServerReset_AfterHeaders_ClientBodyThrows(string scheme) + { + var receivedHeaders = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + await context.Response.BodyWriter.FlushAsync(); + await receivedHeaders.Task.DefaultTimeout(); + context.Features.Get<IHttpResetFeature>().Reset(8); // Cancel + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + response.EnsureSuccessStatusCode(); + receivedHeaders.SetResult(0); + var exception = await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.ReadAsStringAsync()).DefaultTimeout(); + Assert.Equal("The HTTP/2 server reset the stream. HTTP/2 error code 'CANCEL' (0x8).", exception?.InnerException?.InnerException.Message); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ServerReset_AfterEndStream_NoError(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + await context.Response.WriteAsync("Hello World"); + await context.Response.CompleteAsync(); + context.Features.Get<IHttpResetFeature>().Reset(8); // Cancel + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + response.EnsureSuccessStatusCode(); + var body = await response.Content.ReadAsStringAsync().DefaultTimeout(); + Assert.Equal("Hello World", body); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ServerReset_AfterTrailers_NoError(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + context.Response.DeclareTrailer("TestTrailer"); + await context.Response.WriteAsync("Hello World"); + context.Response.AppendTrailer("TestTrailer", "TestValue"); + await context.Response.CompleteAsync(); + context.Features.Get<IHttpResetFeature>().Reset(8); // Cancel + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + Assert.Equal(HttpVersion.Version20, response.Version); + Assert.Equal("TestTrailer", response.Headers.Trailer.Single()); + var responseBody = await response.Content.ReadAsStringAsync().DefaultTimeout(); + Assert.Equal("Hello World", responseBody); + // The response is buffered, we must already have the trailers. + Assert.Equal("TestValue", response.TrailingHeaders.GetValues("TestTrailer").Single()); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ServerReset_BeforeRequestBody_ClientBodyThrows(string scheme) + { + var clientEcho = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously); + var serverReset = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var headersReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + context.Response.ContentType = "text/plain"; + await context.Response.BodyWriter.FlushAsync(); + await headersReceived.Task.DefaultTimeout(); + context.Features.Get<IHttpResetFeature>().Reset(8); // Cancel + serverReset.SetResult(0); + + try + { + using var streamReader = new StreamReader(context.Request.Body); + var read = await streamReader.ReadToEndAsync().DefaultTimeout(); + clientEcho.SetResult(read); + } + catch (Exception ex) + { + clientEcho.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + // The client doesn't flush the headers for requests with a body unless a continue is expected. + client.DefaultRequestHeaders.ExpectContinue = true; + + var streamingContent = new StreamingContent(); + var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); + using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + headersReceived.SetResult(0); + + Assert.Equal(HttpVersion.Version20, response.Version); + + await serverReset.Task.DefaultTimeout(); + var responseEx = await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.ReadAsStringAsync().DefaultTimeout()); + Assert.Contains("The HTTP/2 server reset the stream. HTTP/2 error code 'CANCEL' (0x8)", responseEx.ToString()); + await Assert.ThrowsAsync<TaskCanceledException>(() => streamingContent.SendAsync("Hello World").DefaultTimeout()); + await Assert.ThrowsAnyAsync<OperationCanceledException>(() => clientEcho.Task.DefaultTimeout()); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ServerReset_BeforeRequestBodyEnd_ClientBodyThrows(string scheme) + { + var clientEcho = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously); + var serverReset = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var responseHeadersReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + var count = await context.Request.Body.ReadAsync(new byte[11], 0, 11); + Assert.Equal(11, count); + + context.Response.ContentType = "text/plain"; + await context.Response.BodyWriter.FlushAsync(); + await responseHeadersReceived.Task.DefaultTimeout(); + context.Features.Get<IHttpResetFeature>().Reset(8); // Cancel + serverReset.SetResult(0); + + try + { + using var streamReader = new StreamReader(context.Request.Body); + var read = await streamReader.ReadToEndAsync().DefaultTimeout(); + clientEcho.SetResult(read); + } + catch (Exception ex) + { + clientEcho.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var streamingContent = new StreamingContent(); + var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); + var requestTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + await streamingContent.SendAsync("Hello World").DefaultTimeout(); + using var response = await requestTask; + responseHeadersReceived.SetResult(0); + + Assert.Equal(HttpVersion.Version20, response.Version); + + await serverReset.Task.DefaultTimeout(); + var responseEx = await Assert.ThrowsAsync<HttpRequestException>(() => response.Content.ReadAsStringAsync().DefaultTimeout()); + Assert.Contains("The HTTP/2 server reset the stream. HTTP/2 error code 'CANCEL' (0x8)", responseEx.ToString()); + await Assert.ThrowsAsync<TaskCanceledException>(() => streamingContent.SendAsync("Hello World").DefaultTimeout()); + await Assert.ThrowsAnyAsync<OperationCanceledException>(() => clientEcho.Task.DefaultTimeout()); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ClientReset_BeforeRequestData_ReadThrows(string scheme) + { + var requestReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + try + { + var readTask = context.Request.Body.ReadAsync(new byte[11], 0, 11); + requestReceived.SetResult(0); + var ex = await Assert.ThrowsAsync<IOException>(() => readTask).DefaultTimeout(); + serverResult.SetResult(0); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + // The client doesn't flush the headers for requests with a body unless a continue is expected. + client.DefaultRequestHeaders.ExpectContinue = true; + + var streamingContent = new StreamingContent(); + var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); + var requestTask = client.SendAsync(request); + await requestReceived.Task.DefaultTimeout(); + await streamingContent.SendStarted.DefaultTimeout(); + streamingContent.Abort(); + await serverResult.Task.DefaultTimeout(); + await Assert.ThrowsAnyAsync<Exception>(() => requestTask).DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ClientReset_BeforeRequestDataEnd_ReadThrows(string scheme) + { + var requestReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + try + { + await ReadStreamHelloWorld(context.Request.Body); + var readTask = context.Request.Body.ReadAsync(new byte[11], 0, 11); + requestReceived.SetResult(0); + var ex = await Assert.ThrowsAsync<IOException>(() => readTask).DefaultTimeout(); + serverResult.SetResult(0); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var streamingContent = new StreamingContent(); + var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); + var requestTask = client.SendAsync(request); + await streamingContent.SendAsync("Hello World").DefaultTimeout(); + await requestReceived.Task.DefaultTimeout(); + streamingContent.Abort(); + await serverResult.Task.DefaultTimeout(); + await Assert.ThrowsAnyAsync<Exception>(() => requestTask).DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ClientReset_BeforeResponse_ResponseSuppressed(string scheme) + { + var requestReceived = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + try + { + context.RequestAborted.Register(() => serverResult.SetResult(0)); + requestReceived.SetResult(0); + await serverResult.Task.DefaultTimeout(); + await context.Response.WriteAsync("Hello World").DefaultTimeout(); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var requestCancellation = new CancellationTokenSource(); + var requestTask = client.GetAsync(url, requestCancellation.Token); + await requestReceived.Task.DefaultTimeout(); + requestCancellation.Cancel(); + await serverResult.Task.DefaultTimeout(); + await Assert.ThrowsAsync<TaskCanceledException>(() => requestTask).DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ClientReset_BeforeEndStream_WritesSuppressed(string scheme) + { + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + try + { + context.RequestAborted.Register(() => serverResult.SetResult(0)); + await context.Response.WriteAsync("Hello World").DefaultTimeout(); + await serverResult.Task.DefaultTimeout(); + await context.Response.WriteAsync("Hello World").DefaultTimeout(); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); + await ReadStreamHelloWorld(responseStream); + responseStream.Dispose(); // Sends reset + await serverResult.Task.DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ClientReset_BeforeTrailers_TrailersSuppressed(string scheme) + { + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + try + { + context.RequestAborted.Register(() => serverResult.SetResult(0)); + await context.Response.WriteAsync("Hello World").DefaultTimeout(); + await serverResult.Task.DefaultTimeout(); + context.Response.AppendTrailer("foo", "bar"); + await context.Response.CompleteAsync(); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); + var responseStream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); + await ReadStreamHelloWorld(responseStream); + responseStream.Dispose(); // Sends reset + await serverResult.Task.DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [Flaky("https://github.com/dotnet/runtime/issues/860", FlakyOn.All)] + [MemberData(nameof(SupportedSchemes))] + public async Task RequestHeaders_MultipleFrames_Accepted(string scheme) + { + var oneKbString = new string('a', 1024); + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + try + { + for (var i = 0; i < 20; i++) + { + Assert.Equal(oneKbString + i, context.Request.Headers["header" + i]); + } + serverResult.SetResult(0); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + return Task.CompletedTask; + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var request = CreateRequestMessage(HttpMethod.Get, url, content: null); + // The default frame size limit is 16kb, and the total header size limit is 32kb. + for (var i = 0; i < 20; i++) + { + request.Headers.Add("header" + i, oneKbString + i); + } + request.Headers.Host = "localhost"; // The default Host header has a random port value wich can cause the length to vary. + var requestTask = client.SendAsync(request); + var response = await requestTask.DefaultTimeout(); + await serverResult.Task.DefaultTimeout(); + response.EnsureSuccessStatusCode(); + + Assert.Single(TestSink.Writes.Where(context => context.Message.Contains("received HEADERS frame for stream ID 1 with length 16384 and flags END_STREAM"))); + Assert.Single(TestSink.Writes.Where(context => context.Message.Contains("received CONTINUATION frame for stream ID 1 with length 4390 and flags END_HEADERS"))); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ResponseHeaders_MultipleFrames_Accepted(string scheme) + { + var oneKbString = new string('a', 1024); + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + try + { + // The default frame size limit is 16kb, and the total header size limit is 64kb. + for (var i = 0; i < 59; i++) + { + context.Response.Headers.Append("header" + i, oneKbString + i); + } + serverResult.SetResult(0); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + return Task.CompletedTask; + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + var response = await client.GetAsync(url).DefaultTimeout(); + await serverResult.Task.DefaultTimeout(); + response.EnsureSuccessStatusCode(); + for (var i = 0; i < 59; i++) + { + Assert.Equal(oneKbString + i, response.Headers.GetValues("header" + i).Single()); + } + + Assert.Single(TestSink.Writes.Where(context => context.Message.Contains("sending HEADERS frame for stream ID 1 with length 15636 and flags END_STREAM"))); + Assert.Equal(2, TestSink.Writes.Where(context => context.Message.Contains("sending CONTINUATION frame for stream ID 1 with length 15585 and flags NONE")).Count()); + Assert.Single(TestSink.Writes.Where(context => context.Message.Contains("sending CONTINUATION frame for stream ID 1 with length 14546 and flags END_HEADERS"))); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + // Expect this to change when the client implements dynamic request header compression. + // Will the client send the first headers before receiving our settings frame? + // We'll probobly need to ensure the settings changes are ack'd before enforcing them. + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_HeaderTableSize_CanBeReduced_Server(string scheme) + { + var oneKbString = new string('a', 1024); + var serverResult = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureKestrel(options => + { + // Must be larger than 0, should disable header compression + options.Limits.Http2.HeaderTableSize = 1; + }); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + try + { + for (var i = 0; i < 14; i++) + { + Assert.Equal(oneKbString + i, context.Request.Headers["header" + i]); + } + serverResult.SetResult(0); + } + catch (Exception ex) + { + serverResult.SetException(ex); + } + return Task.CompletedTask; + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var request = CreateRequestMessage(HttpMethod.Get, url, content: null); + // The default frame size limit is 16kb, and the total header size limit is 32kb. + for (var i = 0; i < 14; i++) + { + request.Headers.Add("header" + i, oneKbString + i); + } + request.Headers.Host = "localhost"; // The default Host has a random port value that causes the length to very. + var requestTask = client.SendAsync(request); + var response = await requestTask.DefaultTimeout(); + await serverResult.Task.DefaultTimeout(); + response.EnsureSuccessStatusCode(); + + Assert.Single(TestSink.Writes.Where(context + => context.Message.Contains("received HEADERS frame for stream ID 1 with length 14540 and flags END_STREAM, END_HEADERS"))); + + await host.StopAsync().DefaultTimeout(); + } + + // Settings_HeaderTableSize_CanBeReduced_Client - The client uses the default 4k HPACK dynamic table size and it cannot be changed. + // Nor does Kestrel yet support sending dynaimc table updates, so there's nothing to test here. https://github.com/dotnet/aspnetcore/issues/4715 + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_MaxConcurrentStreamsGet_Server(string scheme) + { + var sync = new SemaphoreSlim(5); + var requestCount = 0; + var requestBlock = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureKestrel(options => + { + options.Limits.Http2.MaxStreamsPerConnection = 5; + }); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + // The stream limit should mean we never hit the semaphore limit. + Assert.True(sync.Wait(0)); + var count = Interlocked.Increment(ref requestCount); + + if (count == 5) + { + requestBlock.TrySetResult(0); + } + else + { + await requestBlock.Task.DefaultTimeout(); + } + + sync.Release(); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var tasks = new List<Task<HttpResponseMessage>>(10); + for (var i = 0; i < 10; i++) + { + var requestTask = client.GetAsync(url).DefaultTimeout(); + tasks.Add(requestTask); + } + + var responses = await Task.WhenAll(tasks.ToList()).DefaultTimeout(); + foreach (var response in responses) + { + response.EnsureSuccessStatusCode(); + } + + // SKIP: https://github.com/dotnet/aspnetcore/issues/17842 + // The client initially issues all 10 requests before receiving the settings, has 5 refused (after receiving the settings), + // waits for the first 5 to finish, retries the refused 5, and in the end each request completes sucesfully despite the logged errors. + // Assert.Empty(TestSink.Writes.Where(context => context.Message.Contains("HTTP/2 stream error"))); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_MaxConcurrentStreamsPost_Server(string scheme) + { + var sync = new SemaphoreSlim(5); + var requestCount = 0; + var requestBlock = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureKestrel(options => + { + options.Limits.Http2.MaxStreamsPerConnection = 5; + }); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + // The stream limit should mean we never hit the semaphore limit. + Assert.True(sync.Wait(0)); + var count = Interlocked.Increment(ref requestCount); + + if (count == 5) + { + requestBlock.TrySetResult(0); + } + else + { + await requestBlock.Task.DefaultTimeout(); + } + + sync.Release(); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + + var tasks = new List<Task<HttpResponseMessage>>(10); + for (var i = 0; i < 10; i++) + { + var requestTask = client.PostAsync(url, new StringContent("Hello World")).DefaultTimeout(); + tasks.Add(requestTask); + } + + var responses = await Task.WhenAll(tasks.ToList()).DefaultTimeout(); + foreach (var response in responses) + { + response.EnsureSuccessStatusCode(); + } + + // SKIP: https://github.com/dotnet/aspnetcore/issues/17842 + // The client initially issues all 10 requests before receiving the settings, has 5 refused (after receiving the settings), + // waits for the first 5 to finish, retries the refused 5, and in the end each request completes sucesfully despite the logged errors. + // Assert.Empty(TestSink.Writes.Where(context => context.Message.Contains("HTTP/2 stream error"))); + + await host.StopAsync().DefaultTimeout(); + } + + // Settings_MaxConcurrentStreams_Client - Neither client or server support Push, nothing to test in this direction. + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_MaxFrameSize_Larger_Server(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureKestrel(options => options.Limits.Http2.MaxFrameSize = 1024 * 20); // The default is 16kb + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => context.Response.WriteAsync("Hello World"))); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + // Send an initial request to ensure the settings get synced before the real test. + var responseBody = await client.GetStringAsync(url).DefaultTimeout(); + Assert.Equal("Hello World", responseBody); + + var response = await client.PostAsync(url, new ByteArrayContent(new byte[1024 * 18])).DefaultTimeout(); + response.EnsureSuccessStatusCode(); + Assert.Equal("Hello World", await response.Content.ReadAsStringAsync()); + + // SKIP: The client does not take advantage of a larger allowed frame size. + // https://github.com/dotnet/runtime/blob/48a78bfa13e9c710851690621fc2c0fe1637802c/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs#L483-L488 + // Assert.Single(TestSink.Writes.Where(context => context.Message.Contains("received DATA frame for stream ID 1 with length 18432 and flags NONE"))); + + await host.StopAsync().DefaultTimeout(); + } + + // Settings_MaxFrameSize_Larger_Client - Not configurable + + [Theory] + [Flaky("https://github.com/dotnet/runtime/issues/860", FlakyOn.All)] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_MaxHeaderListSize_Server(string scheme) + { + var oneKbString = new string('a', 1024); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => throw new NotImplementedException() )); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + // There's no point in waiting for the settings to sync, the client doesn't check the header list size setting. + // https://github.com/dotnet/runtime/blob/48a78bfa13e9c710851690621fc2c0fe1637802c/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs#L467-L494 + + var request = CreateRequestMessage(HttpMethod.Get, url, content: null); + // The default size limit is 32kb. + for (var i = 0; i < 33; i++) + { + request.Headers.Add("header" + i, oneKbString + i); + } + // Kestrel closes the connection rather than sending the recommended 431 response. https://github.com/dotnet/aspnetcore/issues/17861 + await Assert.ThrowsAsync<HttpRequestException>(() => client.SendAsync(request)).DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_MaxHeaderListSize_Client(string scheme) + { + var oneKbString = new string('a', 1024); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + // The total header size limit is 64kb. + for (var i = 0; i < 65; i++) + { + context.Response.Headers.Append("header" + i, oneKbString + i); + } + return Task.CompletedTask; + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + + using var client = CreateClient(); + var ex = await Assert.ThrowsAsync<HttpRequestException>(() => client.GetAsync(url)).DefaultTimeout(); + Assert.Equal("The HTTP response headers length exceeded the set limit of 65536 bytes.", ex.InnerException?.InnerException?.Message); + + await host.StopAsync().DefaultTimeout(); + } + + // Settings_InitialWindowSize_Lower_Server - Kestrel does not support lowering the InitialStreamWindowSize below the spec default 64kb. + // Settings_InitialWindowSize_Lower_Client - Not configurable. + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_InitialWindowSize_Server(string scheme) + { + var requestFinished = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + await requestFinished.Task.DefaultTimeout(); + + await context.Response.WriteAsync("Hello World"); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + + var streamingContent = new StreamingContent(); + var requestTask = client.PostAsync(url, streamingContent); + + // The spec default window is 64kb-1 and Kestrel's default is 96kb. + // We should be able to send the entire request body without getting blocked by flow control. + var oneKbString = new string('a', 1024); + for (var i = 0; i < 96; i++) + { + await streamingContent.SendAsync(oneKbString).DefaultTimeout(); + } + streamingContent.Complete(); + requestFinished.SetResult(0); + + var response = await requestTask.DefaultTimeout(); + response.EnsureSuccessStatusCode(); + Assert.Equal("Hello World", await response.Content.ReadAsStringAsync()); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task Settings_InitialWindowSize_Client(string scheme) + { + var responseFinished = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + // The spec default window is 64kb - 1. + // We should be able to send the entire response body without getting blocked by flow control. + var oneKbString = new string('a', 1024); + for (var i = 0; i < 63; i++) + { + await context.Response.WriteAsync(oneKbString).DefaultTimeout(); + } + await context.Response.WriteAsync(new string('a', 1023)).DefaultTimeout(); + await context.Response.CompleteAsync().DefaultTimeout(); + responseFinished.SetResult(0); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + + var requestTask = client.GetStreamAsync(url); + await responseFinished.Task.DefaultTimeout(); + var response = await requestTask.DefaultTimeout(); + + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task ConnectionWindowSize_Server(string scheme) + { + var requestFinished = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously); + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(async context => + { + await requestFinished.Task.DefaultTimeout(); + var buffer = new byte[1024]; + var read = 0; + do + { + read = await context.Request.Body.ReadAsync(buffer, 0, buffer.Length).DefaultTimeout(); + } while (read > 0); + + await context.Response.WriteAsync("Hello World"); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + + var streamingContent0 = new StreamingContent(); + var streamingContent1 = new StreamingContent(); + var requestTask0 = client.PostAsync(url, streamingContent0); + var requestTask1 = client.PostAsync(url, streamingContent1); + + // The spec default connection window is 64kb-1 and Kestrel's default is 128kb. + // We should be able to send two 64kb requests without getting blocked by flow control. + var oneKbString = new string('a', 1024); + for (var i = 0; i < 64; i++) + { + await streamingContent0.SendAsync(oneKbString).DefaultTimeout(); + await streamingContent1.SendAsync(oneKbString).DefaultTimeout(); + } + streamingContent0.Complete(); + streamingContent1.Complete(); + requestFinished.SetResult(0); + + var response0 = await requestTask0.DefaultTimeout(); + var response1 = await requestTask0.DefaultTimeout(); + response0.EnsureSuccessStatusCode(); + response1.EnsureSuccessStatusCode(); + Assert.Equal("Hello World", await response0.Content.ReadAsStringAsync()); + Assert.Equal("Hello World", await response1.Content.ReadAsStringAsync()); + + await host.StopAsync().DefaultTimeout(); + } + + // ConnectionWindowSize_Client - impractical + // The spec default connection window is 64kb - 1 but the client default is 64Mb (not configurable). + // The client restricts streams to 64kb - 1 so we would need to issue 64 * 1024 requests to stress the connection window limit. + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task UnicodeRequestHost(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => + { + Assert.Equal("點.看", context.Request.Host.Host); + return context.Response.WriteAsync(context.Request.Host.Host); + })); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + var request = CreateRequestMessage(HttpMethod.Get, url, content: null); + request.Headers.Host = "xn--md7a.xn--c1y"; // Punycode + var response = await client.SendAsync(request).DefaultTimeout(); + response.EnsureSuccessStatusCode(); + Assert.Equal("點.看", await response.Content.ReadAsStringAsync()); + await host.StopAsync().DefaultTimeout(); + } + + [Theory] + [MemberData(nameof(SupportedSchemes))] + public async Task UrlEncoding(string scheme) + { + var hostBuilder = new HostBuilder() + .ConfigureWebHost(webHostBuilder => + { + ConfigureKestrel(webHostBuilder, scheme); + webHostBuilder.ConfigureServices(AddTestLogging) + .Configure(app => app.Run(context => context.Response.WriteAsync(context.Request.Path.Value))); + }); + using var host = await hostBuilder.StartAsync().DefaultTimeout(); + + var url = host.MakeUrl(scheme); + using var client = CreateClient(); + // Skipped controls, '?' and '#'. + var response = await client.GetAsync(url + " !\"$%&'()*++,-./0123456789:;<>=@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~點看").DefaultTimeout(); + response.EnsureSuccessStatusCode(); + Assert.Equal("/ !\"$%&'()*++,-./0123456789:;<>=@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`{|}~點看", await response.Content.ReadAsStringAsync()); + await host.StopAsync().DefaultTimeout(); } private static HttpClient CreateClient() @@ -552,8 +1634,16 @@ namespace Interop.FunctionalTests private static async Task ReadStreamHelloWorld(Stream stream) { var responseBuffer = new byte["Hello World".Length]; - var read = await stream.ReadAsync(responseBuffer, 0, responseBuffer.Length).DefaultTimeout(); - Assert.Equal(responseBuffer.Length, read); + var totalRead = 0; + do + { + var read = await stream.ReadAsync(responseBuffer, totalRead, responseBuffer.Length - totalRead).DefaultTimeout(); + totalRead += read; + if (read == 0) + { + throw new InvalidOperationException("Unexpected end of stream"); + } + } while (totalRead < responseBuffer.Length); Assert.Equal("Hello World", Encoding.UTF8.GetString(responseBuffer)); } } diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj b/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj index 3a1b3e7670..e5c19de1eb 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Interop.FunctionalTests.csproj @@ -6,7 +6,7 @@ <TestGroupName>Interop.FunctionalTests</TestGroupName> <!-- WebDriver is not strong named, so this test assembly cannot be strong-named either. --> <SignAssembly>false</SignAssembly> - <!-- See: https://github.com/aspnet/AspNetCore/issues/7299 --> + <!-- See: https://github.com/dotnet/aspnetcore/issues/7299 --> <BuildHelixPayload>false</BuildHelixPayload> </PropertyGroup> diff --git a/src/Servers/Kestrel/test/Interop.FunctionalTests/Utilities.cs b/src/Servers/Kestrel/test/Interop.FunctionalTests/Utilities.cs index a8223118a0..1e6fb930f8 100644 --- a/src/Servers/Kestrel/test/Interop.FunctionalTests/Utilities.cs +++ b/src/Servers/Kestrel/test/Interop.FunctionalTests/Utilities.cs @@ -14,7 +14,7 @@ namespace Interop.FunctionalTests // "Missing SslStream ALPN support: https://github.com/dotnet/corefx/issues/30492" && new OSSkipConditionAttribute(OperatingSystems.MacOSX).IsMet // Debian 8 uses OpenSSL 1.0.1 which does not support ALPN - && new SkipOnHelixAttribute("https://github.com/aspnet/AspNetCore/issues/10428") { Queues = "Debian.8.Amd64.Open" }.IsMet; + && new SkipOnHelixAttribute("https://github.com/dotnet/aspnetcore/issues/10428") { Queues = "Debian.8.Amd64.Open" }.IsMet; } } } diff --git a/src/Servers/Kestrel/test/Libuv.BindTests/Libuv.BindTests.csproj b/src/Servers/Kestrel/test/Libuv.BindTests/Libuv.BindTests.csproj index 22cabcb14a..39871045f6 100644 --- a/src/Servers/Kestrel/test/Libuv.BindTests/Libuv.BindTests.csproj +++ b/src/Servers/Kestrel/test/Libuv.BindTests/Libuv.BindTests.csproj @@ -7,7 +7,7 @@ </PropertyGroup> <ItemGroup> - <!-- https://github.com/aspnet/AspNetCore/issues/8046 --> + <!-- https://github.com/dotnet/aspnetcore/issues/8046 --> <HelixProjectPlatform Remove="OSX" /> </ItemGroup> diff --git a/src/Servers/Kestrel/test/Sockets.BindTests/SocketTransportFactoryTests.cs b/src/Servers/Kestrel/test/Sockets.BindTests/SocketTransportFactoryTests.cs new file mode 100644 index 0000000000..2ff92f497f --- /dev/null +++ b/src/Servers/Kestrel/test/Sockets.BindTests/SocketTransportFactoryTests.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Moq; +using Xunit; + +namespace Sockets.BindTests +{ + public class SocketTransportFactoryTests + { + [Fact] + public async Task ThrowsNotSupportedExceptionWhenBindingToFileHandleEndPoint() + { + var socketTransportFactory = new SocketTransportFactory(Options.Create(new SocketTransportOptions()), Mock.Of<ILoggerFactory>()); + await Assert.ThrowsAsync<NotSupportedException>(async () => await socketTransportFactory.BindAsync(new FileHandleEndPoint(0, FileHandleType.Auto))); + } + } +} + diff --git a/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj b/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj index d0431dbb29..7337ccfc0c 100644 --- a/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj +++ b/src/Servers/Kestrel/tools/CodeGenerator/CodeGenerator.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> @@ -18,7 +18,7 @@ <PropertyGroup> <StartWorkingDirectory>$(MSBuildThisFileDirectory)..\..\</StartWorkingDirectory> - <StartArguments>Core/src/Internal/Http/HttpHeaders.Generated.cs Core/src/Internal/Http/HttpProtocol.Generated.cs Core/src/Internal/Infrastructure/HttpUtilities.Generated.cs shared/TransportConnection.Generated.cs</StartArguments> + <StartArguments>Core/src/Internal/Http/HttpHeaders.Generated.cs Core/src/Internal/Http/HttpProtocol.Generated.cs Core/src/Internal/Infrastructure/HttpUtilities.Generated.cs shared/TransportConnection.Generated.cs Core/src/Internal/Http2/Http2Connection.Generated.cs</StartArguments> </PropertyGroup> </Project> diff --git a/src/Servers/Kestrel/tools/CodeGenerator/Http2Connection.cs b/src/Servers/Kestrel/tools/CodeGenerator/Http2Connection.cs new file mode 100644 index 0000000000..6cfabb9962 --- /dev/null +++ b/src/Servers/Kestrel/tools/CodeGenerator/Http2Connection.cs @@ -0,0 +1,33 @@ +// 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.Collections.Generic; +using Microsoft.Net.Http.Headers; + +namespace CodeGenerator +{ + public static class Http2Connection + { + public static string GenerateFile() + { + return ReadOnlySpanStaticDataGenerator.GenerateFile( + namespaceName: "Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2", + className: "Http2Connection", + allProperties: GetStrings()); + } + + private static IEnumerable<(string Name, string Value)> GetStrings() + { + yield return ("ClientPreface", "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"); + yield return ("Authority", HeaderNames.Authority); + yield return ("Method", HeaderNames.Method); + yield return ("Path", HeaderNames.Path); + yield return ("Scheme", HeaderNames.Scheme); + yield return ("Status", HeaderNames.Status); + yield return ("Connection", "connection"); + yield return ("Te", "te"); + yield return ("Trailers", "trailers"); + yield return ("Connect", "CONNECT"); + } + } +} diff --git a/src/Servers/Kestrel/tools/CodeGenerator/Program.cs b/src/Servers/Kestrel/tools/CodeGenerator/Program.cs index eb687fccac..c319d9bfb3 100644 --- a/src/Servers/Kestrel/tools/CodeGenerator/Program.cs +++ b/src/Servers/Kestrel/tools/CodeGenerator/Program.cs @@ -30,8 +30,13 @@ namespace CodeGenerator Console.Error.WriteLine("Missing path to TransportConnection.Generated.cs"); return 1; } + else if (args.Length < 5) + { + Console.Error.WriteLine("Missing path to Http2Connection.Generated.cs"); + return 1; + } - Run(args[0], args[1], args[2], args[3]); + Run(args[0], args[1], args[2], args[3], args[4]); return 0; } @@ -40,12 +45,14 @@ namespace CodeGenerator string knownHeadersPath, string httpProtocolFeatureCollectionPath, string httpUtilitiesPath, - string transportConnectionFeatureCollectionPath) + string transportConnectionFeatureCollectionPath, + string http2ConnectionPath) { var knownHeadersContent = KnownHeaders.GeneratedFile(); var httpProtocolFeatureCollectionContent = HttpProtocolFeatureCollection.GenerateFile(); var httpUtilitiesContent = HttpUtilities.HttpUtilities.GeneratedFile(); var transportConnectionFeatureCollectionContent = TransportConnectionFeatureCollection.GenerateFile(); + var http2ConnectionContent = Http2Connection.GenerateFile(); var existingKnownHeaders = File.Exists(knownHeadersPath) ? File.ReadAllText(knownHeadersPath) : ""; if (!string.Equals(knownHeadersContent, existingKnownHeaders)) @@ -70,6 +77,12 @@ namespace CodeGenerator { File.WriteAllText(transportConnectionFeatureCollectionPath, transportConnectionFeatureCollectionContent); } + + var existingHttp2Connection = File.Exists(http2ConnectionPath) ? File.ReadAllText(http2ConnectionPath) : ""; + if (!string.Equals(http2ConnectionContent, existingHttp2Connection)) + { + File.WriteAllText(http2ConnectionPath, http2ConnectionContent); + } } } } diff --git a/src/Servers/Kestrel/tools/CodeGenerator/ReadOnlySpanStaticDataGenerator.cs b/src/Servers/Kestrel/tools/CodeGenerator/ReadOnlySpanStaticDataGenerator.cs new file mode 100644 index 0000000000..1689292eb5 --- /dev/null +++ b/src/Servers/Kestrel/tools/CodeGenerator/ReadOnlySpanStaticDataGenerator.cs @@ -0,0 +1,78 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CodeGenerator +{ + public static class ReadOnlySpanStaticDataGenerator + { + public static string GenerateFile(string namespaceName, string className, IEnumerable<(string Name, string Value)> allProperties) + { + var properties = allProperties.Select((p, index) => new Property + { + Data = p, + Index = index + }); + + return $@"// 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; + +namespace {namespaceName} +{{ + internal partial class {className} + {{ + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + {Each(properties, p => $@" + private static ReadOnlySpan<byte> {p.Data.Name}Bytes => new byte[{p.Data.Value.Length}] {{ {GetDataAsBytes(p.Data.Value)} }};")} + }} +}} +"; + } + + private static string Each<T>(IEnumerable<T> values, Func<T, string> formatter) + { + return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : ""; + } + + private static string GetDataAsBytes(string value) + { + var stringBuilder = new StringBuilder(); + + for (var i = 0; i < value.Length; ++i) + { + var c = value[i]; + if (c == '\n') + { + stringBuilder.Append("(byte)'\\n'"); + } + else if (c == '\r') + { + stringBuilder.Append("(byte)'\\r'"); + } + else + { + stringBuilder.AppendFormat("(byte)'{0}'", c); + } + + if (i < value.Length - 1) + { + stringBuilder.Append(", "); + } + } + + return stringBuilder.ToString(); + } + + private class Property + { + public (string Name, string Value) Data; + public int Index; + } + } +} diff --git a/src/Servers/test/FunctionalTests/HelloWorldTest.cs b/src/Servers/test/FunctionalTests/HelloWorldTest.cs index e047288908..cf20b9d617 100644 --- a/src/Servers/test/FunctionalTests/HelloWorldTest.cs +++ b/src/Servers/test/FunctionalTests/HelloWorldTest.cs @@ -21,7 +21,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Kestrel, ServerType.Nginx, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithApplicationTypes(ApplicationType.Portable) .WithAllHostingModels() .WithAllArchitectures(); diff --git a/src/Servers/test/FunctionalTests/NtlmAuthenticationTest.cs b/src/Servers/test/FunctionalTests/NtlmAuthenticationTest.cs index 330586eafa..75ef46207a 100644 --- a/src/Servers/test/FunctionalTests/NtlmAuthenticationTest.cs +++ b/src/Servers/test/FunctionalTests/NtlmAuthenticationTest.cs @@ -22,7 +22,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix TestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.HttpSys, ServerType.Kestrel) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllHostingModels(); [ConditionalTheory] diff --git a/src/Servers/test/FunctionalTests/ResponseCompressionTests.cs b/src/Servers/test/FunctionalTests/ResponseCompressionTests.cs index 4f4af0b3e0..e441343521 100644 --- a/src/Servers/test/FunctionalTests/ResponseCompressionTests.cs +++ b/src/Servers/test/FunctionalTests/ResponseCompressionTests.cs @@ -33,7 +33,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix NoCompressionTestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Kestrel, ServerType.Nginx, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllHostingModels(); [ConditionalTheory] @@ -45,7 +45,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix HostCompressionTestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Nginx) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllHostingModels(); [ConditionalTheory] @@ -57,7 +57,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix AppCompressionTestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Kestrel, ServerType.HttpSys) // No pass-through compression for nginx - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllHostingModels(); [ConditionalTheory] @@ -69,7 +69,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix HostAndAppCompressionTestVariants => TestMatrix.ForServers(ServerType.IISExpress, ServerType.Kestrel, ServerType.Nginx, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + .WithTfms(Tfm.NetCoreApp50) .WithAllHostingModels(); [ConditionalTheory] diff --git a/src/Servers/test/FunctionalTests/ResponseTests.cs b/src/Servers/test/FunctionalTests/ResponseTests.cs index 169132f30b..c3738f9d16 100644 --- a/src/Servers/test/FunctionalTests/ResponseTests.cs +++ b/src/Servers/test/FunctionalTests/ResponseTests.cs @@ -25,8 +25,8 @@ namespace ServerComparison.FunctionalTests } public static TestMatrix TestVariants - => TestMatrix.ForServers(/* ServerType.IISExpress, https://github.com/aspnet/AspNetCore/issues/6168, */ ServerType.Kestrel, ServerType.Nginx, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31) + => TestMatrix.ForServers(/* ServerType.IISExpress, https://github.com/dotnet/aspnetcore/issues/6168, */ ServerType.Kestrel, ServerType.Nginx, ServerType.HttpSys) + .WithTfms(Tfm.NetCoreApp50) .WithAllHostingModels(); [ConditionalTheory] @@ -52,7 +52,7 @@ namespace ServerComparison.FunctionalTests public static TestMatrix SelfhostTestVariants => TestMatrix.ForServers(ServerType.Kestrel, ServerType.HttpSys) - .WithTfms(Tfm.NetCoreApp31); + .WithTfms(Tfm.NetCoreApp50); // Connection Close tests do not work through reverse proxies [ConditionalTheory] diff --git a/src/Servers/testassets/ServerComparison.TestSites/StartupNtlmAuthentication.cs b/src/Servers/testassets/ServerComparison.TestSites/StartupNtlmAuthentication.cs index c2adffb4db..9fc54386b1 100644 --- a/src/Servers/testassets/ServerComparison.TestSites/StartupNtlmAuthentication.cs +++ b/src/Servers/testassets/ServerComparison.TestSites/StartupNtlmAuthentication.cs @@ -16,7 +16,7 @@ namespace ServerComparison.TestSites public void ConfigureServices(IServiceCollection services) { services.AddHttpContextAccessor(); - // https://github.com/aspnet/AspNetCore/issues/11462 + // https://github.com/dotnet/aspnetcore/issues/11462 // services.AddSingleton<IClaimsTransformation, OneTransformPerRequest>(); // This will deffer to the server implementations when available. @@ -45,7 +45,7 @@ namespace ServerComparison.TestSites }); app.UseAuthentication(); - app.Use((context, next) => + app.Use((context, next) => { if (context.Request.Path.Equals("/Anonymous")) { diff --git a/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs b/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs index 4cbea8a866..fe3e2eb51d 100644 --- a/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs +++ b/src/Shared/Buffers.MemoryPool/DiagnosticMemoryPool.cs @@ -119,7 +119,7 @@ namespace System.Buffers MemoryPoolThrowHelper.ThrowInvalidOperationException_DisposingPoolWithActiveBlocks(_totalBlocks - _blocks.Count, _totalBlocks, _blocks.ToArray()); } - if (_blockAccessExceptions.Any()) + if (_blockAccessExceptions.Count > 0) { throw CreateAccessExceptions(); } @@ -136,7 +136,7 @@ namespace System.Buffers private void SetAllBlocksReturned() { - if (_blockAccessExceptions.Any()) + if (_blockAccessExceptions.Count > 0) { _allBlocksReturned.SetException(CreateAccessExceptions()); } diff --git a/src/Shared/Buffers.MemoryPool/MemoryPoolSlab.cs b/src/Shared/Buffers.MemoryPool/MemoryPoolSlab.cs index 99dfe082e5..a9baa560f5 100644 --- a/src/Shared/Buffers.MemoryPool/MemoryPoolSlab.cs +++ b/src/Shared/Buffers.MemoryPool/MemoryPoolSlab.cs @@ -58,7 +58,7 @@ namespace System.Buffers _isDisposed = true; Array = null; - NativePointer = IntPtr.Zero;; + NativePointer = IntPtr.Zero; if (_gcHandle.IsAllocated) { diff --git a/src/Shared/CertificateGeneration/CertificateManager.cs b/src/Shared/CertificateGeneration/CertificateManager.cs index 09824fb127..c40c9e6413 100644 --- a/src/Shared/CertificateGeneration/CertificateManager.cs +++ b/src/Shared/CertificateGeneration/CertificateManager.cs @@ -752,7 +752,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation result.ResultCode = EnsureCertificateResult.Succeeded; X509Certificate2 certificate = null; - if (certificates.Count() > 0) + if (certificates.Any()) { result.Diagnostics.Debug("Found valid certificates present on the machine."); result.Diagnostics.Debug(result.Diagnostics.DescribeCertificates(certificates)); diff --git a/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs b/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs index 4f1700bb77..098e3d6690 100644 --- a/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs +++ b/src/Shared/ChunkingCookieManager/ChunkingCookieManager.cs @@ -288,7 +288,7 @@ namespace Microsoft.AspNetCore.Internal SameSite = options.SameSite, Secure = options.Secure, IsEssential = options.IsEssential, - Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), + Expires = DateTimeOffset.UnixEpoch, HttpOnly = options.HttpOnly, }); @@ -305,7 +305,7 @@ namespace Microsoft.AspNetCore.Internal SameSite = options.SameSite, Secure = options.Secure, IsEssential = options.IsEssential, - Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), + Expires = DateTimeOffset.UnixEpoch, HttpOnly = options.HttpOnly, }); } diff --git a/src/Shared/E2ETesting/BrowserFixture.cs b/src/Shared/E2ETesting/BrowserFixture.cs index 7808176318..8b3239c5df 100644 --- a/src/Shared/E2ETesting/BrowserFixture.cs +++ b/src/Shared/E2ETesting/BrowserFixture.cs @@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.E2ETesting // To prevent this we let the client attempt several times to connect to the server, increasing // the max allowed timeout for a command on each attempt linearly. // This can also be caused if many tests are running concurrently, we might want to manage - // chrome and chromedriver instances more aggresively if we have to. + // chrome and chromedriver instances more aggressively if we have to. // Additionally, if we think the selenium server has become irresponsive, we could spin up // replace the current selenium server instance and let a new instance take over for the // remaining tests. diff --git a/src/Shared/E2ETesting/SeleniumStandaloneServer.cs b/src/Shared/E2ETesting/SeleniumStandaloneServer.cs index d62b3ffb00..91f80afb2b 100644 --- a/src/Shared/E2ETesting/SeleniumStandaloneServer.cs +++ b/src/Shared/E2ETesting/SeleniumStandaloneServer.cs @@ -191,7 +191,7 @@ Captured output lines: private static Process StartSentinelProcess(Process process, string sentinelFile, int timeout) { - // This sentinel process will start and will kill any roge selenium server that want' torn down + // This sentinel process will start and will kill any rouge selenium server that want' torn down // via normal means. var psi = new ProcessStartInfo { diff --git a/src/Shared/ErrorPage/GeneratePage.ps1 b/src/Shared/ErrorPage/GeneratePage.ps1 index 8bc0f2c07c..94e6746169 100644 --- a/src/Shared/ErrorPage/GeneratePage.ps1 +++ b/src/Shared/ErrorPage/GeneratePage.ps1 @@ -2,7 +2,7 @@ param( [Parameter(Mandatory = $true)][string]$ToolingRepoPath ) -$ToolPath = Join-Path $ToolingRepoPath "artifacts\bin\RazorPageGenerator\Debug\netcoreapp3.1\dotnet-razorpagegenerator.exe" +$ToolPath = Join-Path $ToolingRepoPath "artifacts\bin\RazorPageGenerator\Debug\netcoreapp5.0\dotnet-razorpagegenerator.exe" if (!(Test-Path $ToolPath)) { throw "Unable to find razor page generator tool at $ToolPath" diff --git a/src/Shared/ErrorPage/README.md b/src/Shared/ErrorPage/README.md index 1f74a4e33a..cc0dbc377c 100644 --- a/src/Shared/ErrorPage/README.md +++ b/src/Shared/ErrorPage/README.md @@ -1,13 +1,13 @@ # Error Page -This folder is shared among multiple projects. The `ErrorPage.Designer.cs` and `ErrorPageModel.cs` files are used to render this view. The `ErrorPage.Designer.cs` file is generated by rendering `src/Views/ErrorPage.cshtml` using the [RazorPageGenerator](https://github.com/aspnet/AspNetCore-Tooling/tree/master/src/Razor/src/RazorPageGenerator) tool. +This folder is shared among multiple projects. The `ErrorPage.Designer.cs` and `ErrorPageModel.cs` files are used to render this view. The `ErrorPage.Designer.cs` file is generated by rendering `src/Views/ErrorPage.cshtml` using the [RazorPageGenerator](https://github.com/dotnet/aspnetcore-tooling/tree/master/src/Razor/src/RazorPageGenerator) tool. ## Making changes to ErrorPage.cshtml -1. Clone aspnet/AspNetCore-Tooling +1. Clone dotnet/aspnetcore-tooling 1. Run `./build.cmd` in **that repo** 1. Edit the file -1. Run the `GeneratePage` script, passing in the path to the `aspnet/AspNetCore-Tooling` repo root. +1. Run the `GeneratePage` script, passing in the path to the `dotnet/aspnetcore-tooling` repo root. ``` .\GeneratePage -ToolingRepoPath C:\Code\aspnet\AspNetCore-Tooling diff --git a/src/Shared/ErrorPage/Views/ErrorPage.css b/src/Shared/ErrorPage/Views/ErrorPage.css index 4d3287c12d..1b16b5792c 100644 --- a/src/Shared/ErrorPage/Views/ErrorPage.css +++ b/src/Shared/ErrorPage/Views/ErrorPage.css @@ -98,6 +98,12 @@ body .location { background-color: #fbfbfb; } +#stackpage .frame .source .highlight { + border-left: 3px solid red; + margin-left: -3px; + font-weight: bold; +} + #stackpage .frame .source .highlight li span { color: #FF0000; } diff --git a/src/Shared/Http2/CopyToAspNetCore.cmd b/src/Shared/Http2/CopyToAspNetCore.cmd new file mode 100644 index 0000000000..1785929951 --- /dev/null +++ b/src/Shared/Http2/CopyToAspNetCore.cmd @@ -0,0 +1,14 @@ +@ECHO OFF +SETLOCAL + +if not [%1] == [] (set remote_repo=%1) else (set remote_repo=%ASPNETCORE_REPO%) + +IF [%remote_repo%] == [] ( + echo The 'ASPNETCORE_REPO' environment variable or command line parameter is not set, aborting. + exit /b 1 +) + +echo ASPNETCORE_REPO: %remote_repo% + +robocopy . %remote_repo%\src\Shared\Http2 /MIR +robocopy .\..\..\..\..\..\tests\Tests\System\Net\Http2\ %remote_repo%\src\Shared\test\Shared.Tests\Http2 /MIR diff --git a/src/Shared/Http2/CopyToAspNetCore.sh b/src/Shared/Http2/CopyToAspNetCore.sh new file mode 100644 index 0000000000..f8d073366e --- /dev/null +++ b/src/Shared/Http2/CopyToAspNetCore.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +if [[ -n "$1" ]]; then + remote_repo="$1" +else + remote_repo="$ASPNETCORE_REPO" +fi + +if [[ -z "$remote_repo" ]]; then + echo The 'ASPNETCORE_REPO' environment variable or command line parameter is not set, aborting. + exit 1 +fi + +cd "$(dirname "$0")" || exit 1 + +echo "ASPNETCORE_REPO: $remote_repo" + +rsync -av --delete ./ "$remote_repo"/src/Shared/Http2 +rsync -av --delete ./../../../../../tests/Tests/System/Net/Http2/ "$remote_repo"/src/Shared/test/Shared.Tests/Http2 diff --git a/src/Shared/Http2/CopyToRuntime.cmd b/src/Shared/Http2/CopyToRuntime.cmd new file mode 100644 index 0000000000..7497eadd52 --- /dev/null +++ b/src/Shared/Http2/CopyToRuntime.cmd @@ -0,0 +1,14 @@ +@ECHO OFF +SETLOCAL + +if not [%1] == [] (set remote_repo=%1) else (set remote_repo=%RUNTIME_REPO%) + +IF [%remote_repo%] == [] ( + echo The 'RUNTIME_REPO' environment variable or command line parameter is not set, aborting. + exit /b 1 +) + +echo RUNTIME_REPO: %remote_repo% + +robocopy . %remote_repo%\src\libraries\Common\src\System\Net\Http\Http2 /MIR +robocopy .\..\test\Shared.Tests\Http2 %remote_repo%\src\libraries\Common\tests\Tests\System\Net\Http2 /MIR diff --git a/src/Shared/Http2/CopyToRuntime.sh b/src/Shared/Http2/CopyToRuntime.sh new file mode 100644 index 0000000000..baf10f3b86 --- /dev/null +++ b/src/Shared/Http2/CopyToRuntime.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +if [[ -n "$1" ]]; then + remote_repo="$1" +else + remote_repo="$RUNTIME_REPO" +fi + +if [[ -z "$remote_repo" ]]; then + echo The 'RUNTIME_REPO' environment variable or command line parameter is not set, aborting. + exit 1 +fi + +cd "$(dirname "$0")" || exit 1 + +echo "RUNTIME_REPO: $remote_repo" + +rsync -av --delete ./ "$remote_repo"/src/libraries/Common/src/System/Net/Http/Http2 +rsync -av --delete ./../test/Shared.Tests/Http2/ "$remote_repo"/src/libraries/Common/tests/Tests/System/Net/Http2 diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/DynamicTable.cs b/src/Shared/Http2/Hpack/DynamicTable.cs similarity index 68% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPack/DynamicTable.cs rename to src/Shared/Http2/Hpack/DynamicTable.cs index 7183589021..22178acae7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/DynamicTable.cs +++ b/src/Shared/Http2/Hpack/DynamicTable.cs @@ -1,12 +1,9 @@ // 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. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. -using System; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack +namespace System.Net.Http.HPack { - // The dynamic table is defined as a queue where items are inserted at the front and removed from the back. - // It's implemented as a circular buffer that appends to the end and trims from the front. Thus index are reversed. internal class DynamicTable { private HeaderField[] _buffer; @@ -37,19 +34,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack throw new IndexOutOfRangeException(); } - var modIndex = _insertIndex - index - 1; - if (modIndex < 0) + index = _insertIndex - index - 1; + + if (index < 0) { - modIndex += _buffer.Length; + // _buffer is circular; wrap the index back around. + index += _buffer.Length; } - return _buffer[modIndex]; + return _buffer[index]; } } - public void Insert(Span<byte> name, Span<byte> value) + public void Insert(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { - var entryLength = HeaderField.GetLength(name.Length, value.Length); + int entryLength = HeaderField.GetLength(name.Length, value.Length); EnsureAvailable(entryLength); if (entryLength > _maxSize) @@ -74,12 +73,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack { var newBuffer = new HeaderField[maxSize / HeaderField.RfcOverhead]; - for (var i = 0; i < Count; i++) - { - newBuffer[i] = _buffer[i]; - } + int headCount = Math.Min(_buffer.Length - _removeIndex, _count); + int tailCount = _count - headCount; + + Array.Copy(_buffer, _removeIndex, newBuffer, 0, headCount); + Array.Copy(_buffer, 0, newBuffer, headCount, tailCount); _buffer = newBuffer; + _removeIndex = 0; + _insertIndex = _count; _maxSize = maxSize; } else @@ -93,7 +95,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack { while (_count > 0 && _maxSize - _size < available) { - _size -= _buffer[_removeIndex].Length; + ref HeaderField field = ref _buffer[_removeIndex]; + _size -= field.Length; + field = default; + _count--; _removeIndex = (_removeIndex + 1) % _buffer.Length; } diff --git a/src/Shared/Http2/Hpack/HPackDecoder.cs b/src/Shared/Http2/Hpack/HPackDecoder.cs new file mode 100644 index 0000000000..93c4bfeb9e --- /dev/null +++ b/src/Shared/Http2/Hpack/HPackDecoder.cs @@ -0,0 +1,494 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Buffers; +using System.Diagnostics; +#if KESTREL +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +#endif + +namespace System.Net.Http.HPack +{ + internal class HPackDecoder + { + private enum State + { + Ready, + HeaderFieldIndex, + HeaderNameIndex, + HeaderNameLength, + HeaderNameLengthContinue, + HeaderName, + HeaderValueLength, + HeaderValueLengthContinue, + HeaderValue, + DynamicTableSizeUpdate + } + + public const int DefaultHeaderTableSize = 4096; + public const int DefaultStringOctetsSize = 4096; + public const int DefaultMaxHeadersLength = 64 * 1024; + + // http://httpwg.org/specs/rfc7541.html#rfc.section.6.1 + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 1 | Index (7+) | + // +---+---------------------------+ + private const byte IndexedHeaderFieldMask = 0x80; + private const byte IndexedHeaderFieldRepresentation = 0x80; + + // http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 1 | Index (6+) | + // +---+---+-----------------------+ + private const byte LiteralHeaderFieldWithIncrementalIndexingMask = 0xc0; + private const byte LiteralHeaderFieldWithIncrementalIndexingRepresentation = 0x40; + + // http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | Index (4+) | + // +---+---+-----------------------+ + private const byte LiteralHeaderFieldWithoutIndexingMask = 0xf0; + private const byte LiteralHeaderFieldWithoutIndexingRepresentation = 0x00; + + // http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 1 | Index (4+) | + // +---+---+-----------------------+ + private const byte LiteralHeaderFieldNeverIndexedMask = 0xf0; + private const byte LiteralHeaderFieldNeverIndexedRepresentation = 0x10; + + // http://httpwg.org/specs/rfc7541.html#rfc.section.6.3 + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 1 | Max size (5+) | + // +---+---------------------------+ + private const byte DynamicTableSizeUpdateMask = 0xe0; + private const byte DynamicTableSizeUpdateRepresentation = 0x20; + + // http://httpwg.org/specs/rfc7541.html#rfc.section.5.2 + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | H | String Length (7+) | + // +---+---------------------------+ + private const byte HuffmanMask = 0x80; + + private const int IndexedHeaderFieldPrefix = 7; + private const int LiteralHeaderFieldWithIncrementalIndexingPrefix = 6; + private const int LiteralHeaderFieldWithoutIndexingPrefix = 4; + private const int LiteralHeaderFieldNeverIndexedPrefix = 4; + private const int DynamicTableSizeUpdatePrefix = 5; + private const int StringLengthPrefix = 7; + + private readonly int _maxDynamicTableSize; + private readonly int _maxHeadersLength; + private readonly DynamicTable _dynamicTable; + private readonly IntegerDecoder _integerDecoder = new IntegerDecoder(); + private byte[] _stringOctets; + private byte[] _headerNameOctets; + private byte[] _headerValueOctets; + + private State _state = State.Ready; + private byte[] _headerName; + private int _stringIndex; + private int _stringLength; + private int _headerNameLength; + private int _headerValueLength; + private bool _index; + private bool _huffman; + private bool _headersObserved; + + public HPackDecoder(int maxDynamicTableSize = DefaultHeaderTableSize, int maxHeadersLength = DefaultMaxHeadersLength) + : this(maxDynamicTableSize, maxHeadersLength, new DynamicTable(maxDynamicTableSize)) + { + } + + // For testing. + internal HPackDecoder(int maxDynamicTableSize, int maxHeadersLength, DynamicTable dynamicTable) + { + _maxDynamicTableSize = maxDynamicTableSize; + _maxHeadersLength = maxHeadersLength; + _dynamicTable = dynamicTable; + + _stringOctets = new byte[DefaultStringOctetsSize]; + _headerNameOctets = new byte[DefaultStringOctetsSize]; + _headerValueOctets = new byte[DefaultStringOctetsSize]; + } + + public void Decode(in ReadOnlySequence<byte> data, bool endHeaders, IHttpHeadersHandler handler) + { + foreach (ReadOnlyMemory<byte> segment in data) + { + DecodeInternal(segment.Span, endHeaders, handler); + } + + CheckIncompleteHeaderBlock(endHeaders); + } + + public void Decode(ReadOnlySpan<byte> data, bool endHeaders, IHttpHeadersHandler handler) + { + DecodeInternal(data, endHeaders, handler); + CheckIncompleteHeaderBlock(endHeaders); + } + + private void DecodeInternal(ReadOnlySpan<byte> data, bool endHeaders, IHttpHeadersHandler handler) + { + int intResult; + + for (int i = 0; i < data.Length; i++) + { + byte b = data[i]; + switch (_state) + { + case State.Ready: + // TODO: Instead of masking and comparing each prefix value, + // consider doing a 16-way switch on the first four bits (which is the max prefix size). + // Look at this once we have more concrete perf data. + if ((b & IndexedHeaderFieldMask) == IndexedHeaderFieldRepresentation) + { + _headersObserved = true; + + int val = b & ~IndexedHeaderFieldMask; + + if (_integerDecoder.BeginTryDecode((byte)val, IndexedHeaderFieldPrefix, out intResult)) + { + OnIndexedHeaderField(intResult, handler); + } + else + { + _state = State.HeaderFieldIndex; + } + } + else if ((b & LiteralHeaderFieldWithIncrementalIndexingMask) == LiteralHeaderFieldWithIncrementalIndexingRepresentation) + { + _headersObserved = true; + + _index = true; + int val = b & ~LiteralHeaderFieldWithIncrementalIndexingMask; + + if (val == 0) + { + _state = State.HeaderNameLength; + } + else if (_integerDecoder.BeginTryDecode((byte)val, LiteralHeaderFieldWithIncrementalIndexingPrefix, out intResult)) + { + OnIndexedHeaderName(intResult); + } + else + { + _state = State.HeaderNameIndex; + } + } + else if ((b & LiteralHeaderFieldWithoutIndexingMask) == LiteralHeaderFieldWithoutIndexingRepresentation) + { + _headersObserved = true; + + _index = false; + int val = b & ~LiteralHeaderFieldWithoutIndexingMask; + + if (val == 0) + { + _state = State.HeaderNameLength; + } + else if (_integerDecoder.BeginTryDecode((byte)val, LiteralHeaderFieldWithoutIndexingPrefix, out intResult)) + { + OnIndexedHeaderName(intResult); + } + else + { + _state = State.HeaderNameIndex; + } + } + else if ((b & LiteralHeaderFieldNeverIndexedMask) == LiteralHeaderFieldNeverIndexedRepresentation) + { + _headersObserved = true; + + _index = false; + int val = b & ~LiteralHeaderFieldNeverIndexedMask; + + if (val == 0) + { + _state = State.HeaderNameLength; + } + else if (_integerDecoder.BeginTryDecode((byte)val, LiteralHeaderFieldNeverIndexedPrefix, out intResult)) + { + OnIndexedHeaderName(intResult); + } + else + { + _state = State.HeaderNameIndex; + } + } + else if ((b & DynamicTableSizeUpdateMask) == DynamicTableSizeUpdateRepresentation) + { + // https://tools.ietf.org/html/rfc7541#section-4.2 + // This dynamic table size + // update MUST occur at the beginning of the first header block + // following the change to the dynamic table size. + if (_headersObserved) + { + throw new HPackDecodingException(SR.net_http_hpack_late_dynamic_table_size_update); + } + + if (_integerDecoder.BeginTryDecode((byte)(b & ~DynamicTableSizeUpdateMask), DynamicTableSizeUpdatePrefix, out intResult)) + { + SetDynamicHeaderTableSize(intResult); + } + else + { + _state = State.DynamicTableSizeUpdate; + } + } + else + { + // Can't happen + Debug.Fail("Unreachable code"); + throw new InvalidOperationException("Unreachable code."); + } + + break; + case State.HeaderFieldIndex: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnIndexedHeaderField(intResult, handler); + } + + break; + case State.HeaderNameIndex: + if (_integerDecoder.TryDecode(b, out intResult)) + { + OnIndexedHeaderName(intResult); + } + + break; + case State.HeaderNameLength: + _huffman = (b & HuffmanMask) != 0; + + if (_integerDecoder.BeginTryDecode((byte)(b & ~HuffmanMask), StringLengthPrefix, out intResult)) + { + if (intResult == 0) + { + throw new HPackDecodingException(SR.Format(SR.net_http_invalid_header_name, "")); + } + + OnStringLength(intResult, nextState: State.HeaderName); + } + else + { + _state = State.HeaderNameLengthContinue; + } + + break; + case State.HeaderNameLengthContinue: + if (_integerDecoder.TryDecode(b, out intResult)) + { + // IntegerDecoder disallows overlong encodings, where an integer is encoded with more bytes than is strictly required. + // 0 should always be represented by a single byte, so we shouldn't need to check for it in the continuation case. + Debug.Assert(intResult != 0, "A header name length of 0 should never be encoded with a continuation byte."); + + OnStringLength(intResult, nextState: State.HeaderName); + } + + break; + case State.HeaderName: + _stringOctets[_stringIndex++] = b; + + if (_stringIndex == _stringLength) + { + OnString(nextState: State.HeaderValueLength); + } + + break; + case State.HeaderValueLength: + _huffman = (b & HuffmanMask) != 0; + + if (_integerDecoder.BeginTryDecode((byte)(b & ~HuffmanMask), StringLengthPrefix, out intResult)) + { + OnStringLength(intResult, nextState: State.HeaderValue); + + if (intResult == 0) + { + ProcessHeaderValue(handler); + } + } + else + { + _state = State.HeaderValueLengthContinue; + } + + break; + case State.HeaderValueLengthContinue: + if (_integerDecoder.TryDecode(b, out intResult)) + { + // IntegerDecoder disallows overlong encodings where an integer is encoded with more bytes than is strictly required. + // 0 should always be represented by a single byte, so we shouldn't need to check for it in the continuation case. + Debug.Assert(intResult != 0, "A header value length of 0 should never be encoded with a continuation byte."); + + OnStringLength(intResult, nextState: State.HeaderValue); + } + + break; + case State.HeaderValue: + _stringOctets[_stringIndex++] = b; + + if (_stringIndex == _stringLength) + { + ProcessHeaderValue(handler); + } + + break; + case State.DynamicTableSizeUpdate: + if (_integerDecoder.TryDecode(b, out intResult)) + { + SetDynamicHeaderTableSize(intResult); + _state = State.Ready; + } + + break; + default: + // Can't happen + Debug.Fail("HPACK decoder reach an invalid state"); + throw new NotImplementedException(_state.ToString()); + } + } + } + + private void CheckIncompleteHeaderBlock(bool endHeaders) + { + if (endHeaders) + { + if (_state != State.Ready) + { + throw new HPackDecodingException(SR.net_http_hpack_incomplete_header_block); + } + + _headersObserved = false; + } + } + + private void ProcessHeaderValue(IHttpHeadersHandler handler) + { + OnString(nextState: State.Ready); + + var headerNameSpan = new Span<byte>(_headerName, 0, _headerNameLength); + var headerValueSpan = new Span<byte>(_headerValueOctets, 0, _headerValueLength); + + handler?.OnHeader(headerNameSpan, headerValueSpan); + + if (_index) + { + _dynamicTable.Insert(headerNameSpan, headerValueSpan); + } + } + + public void CompleteDecode() + { + if (_state != State.Ready) + { + // Incomplete header block + throw new HPackDecodingException(SR.net_http_hpack_unexpected_end); + } + } + + private void OnIndexedHeaderField(int index, IHttpHeadersHandler handler) + { + HeaderField header = GetHeader(index); + handler?.OnHeader(header.Name, header.Value); + _state = State.Ready; + } + + private void OnIndexedHeaderName(int index) + { + HeaderField header = GetHeader(index); + _headerName = header.Name; + _headerNameLength = header.Name.Length; + _state = State.HeaderValueLength; + } + + private void OnStringLength(int length, State nextState) + { + if (length > _stringOctets.Length) + { + if (length > _maxHeadersLength) + { + throw new HPackDecodingException(SR.Format(SR.net_http_headers_exceeded_length, _maxHeadersLength)); + } + + _stringOctets = new byte[Math.Max(length, _stringOctets.Length * 2)]; + } + + _stringLength = length; + _stringIndex = 0; + _state = nextState; + } + + private void OnString(State nextState) + { + int Decode(ref byte[] dst) + { + if (_huffman) + { + return Huffman.Decode(new ReadOnlySpan<byte>(_stringOctets, 0, _stringLength), ref dst); + } + else + { + if (dst.Length < _stringLength) + { + dst = new byte[Math.Max(_stringLength, dst.Length * 2)]; + } + + Buffer.BlockCopy(_stringOctets, 0, dst, 0, _stringLength); + return _stringLength; + } + } + + try + { + if (_state == State.HeaderName) + { + _headerNameLength = Decode(ref _headerNameOctets); + _headerName = _headerNameOctets; + } + else + { + _headerValueLength = Decode(ref _headerValueOctets); + } + } + catch (HuffmanDecodingException ex) + { + throw new HPackDecodingException(SR.net_http_hpack_huffman_decode_failed, ex); + } + + _state = nextState; + } + + private HeaderField GetHeader(int index) + { + try + { + return index <= StaticTable.Count + ? StaticTable.Get(index - 1) + : _dynamicTable[index - StaticTable.Count - 1]; + } + catch (IndexOutOfRangeException) + { + // Header index out of range. + throw new HPackDecodingException(SR.Format(SR.net_http_hpack_invalid_index, index)); + } + } + + private void SetDynamicHeaderTableSize(int size) + { + if (size > _maxDynamicTableSize) + { + throw new HPackDecodingException(SR.Format(SR.net_http_hpack_large_table_size_update, size, _maxDynamicTableSize)); + } + + _dynamicTable.Resize(size); + } + } +} diff --git a/src/Shared/Http2/Hpack/HPackDecodingException.cs b/src/Shared/Http2/Hpack/HPackDecodingException.cs new file mode 100644 index 0000000000..63d80cbb9f --- /dev/null +++ b/src/Shared/Http2/Hpack/HPackDecodingException.cs @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Runtime.Serialization; + +namespace System.Net.Http.HPack +{ + // TODO: Should this be public? + [Serializable] + internal class HPackDecodingException : Exception + { + public HPackDecodingException() + { + } + + public HPackDecodingException(string message) : base(message) + { + } + + public HPackDecodingException(string message, Exception innerException) : base(message, innerException) + { + } + + public HPackDecodingException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} diff --git a/src/Shared/Http2/Hpack/HPackEncoder.cs b/src/Shared/Http2/Hpack/HPackEncoder.cs new file mode 100644 index 0000000000..3aa94376be --- /dev/null +++ b/src/Shared/Http2/Hpack/HPackEncoder.cs @@ -0,0 +1,530 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Collections.Generic; +using System.Diagnostics; + +namespace System.Net.Http.HPack +{ + internal class HPackEncoder + { + private IEnumerator<KeyValuePair<string, string>> _enumerator; + + public bool BeginEncode(IEnumerable<KeyValuePair<string, string>> headers, Span<byte> buffer, out int length) + { + _enumerator = headers.GetEnumerator(); + _enumerator.MoveNext(); + + return Encode(buffer, out length); + } + + public bool BeginEncode(int statusCode, IEnumerable<KeyValuePair<string, string>> headers, Span<byte> buffer, out int length) + { + _enumerator = headers.GetEnumerator(); + _enumerator.MoveNext(); + + int statusCodeLength = EncodeStatusCode(statusCode, buffer); + bool done = Encode(buffer.Slice(statusCodeLength), throwIfNoneEncoded: false, out int headersLength); + length = statusCodeLength + headersLength; + + return done; + } + + public bool Encode(Span<byte> buffer, out int length) + { + return Encode(buffer, throwIfNoneEncoded: true, out length); + } + + private bool Encode(Span<byte> buffer, bool throwIfNoneEncoded, out int length) + { + int currentLength = 0; + do + { + if (!EncodeHeader(_enumerator.Current.Key, _enumerator.Current.Value, buffer.Slice(currentLength), out int headerLength)) + { + if (currentLength == 0 && throwIfNoneEncoded) + { + throw new HPackEncodingException(SR.net_http_hpack_encode_failure); + } + + length = currentLength; + return false; + } + + currentLength += headerLength; + } + while (_enumerator.MoveNext()); + + length = currentLength; + + return true; + } + + private int EncodeStatusCode(int statusCode, Span<byte> buffer) + { + switch (statusCode) + { + // Status codes which exist in the HTTP/2 StaticTable. + case 200: + case 204: + case 206: + case 304: + case 400: + case 404: + case 500: + buffer[0] = (byte)(0x80 | StaticTable.StatusIndex[statusCode]); + return 1; + default: + // Send as Literal Header Field Without Indexing - Indexed Name + buffer[0] = 0x08; + + ReadOnlySpan<byte> statusBytes = StatusCodes.ToStatusBytes(statusCode); + buffer[1] = (byte)statusBytes.Length; + statusBytes.CopyTo(buffer.Slice(2)); + + return 2 + statusBytes.Length; + } + } + + private bool EncodeHeader(string name, string value, Span<byte> buffer, out int length) + { + int i = 0; + length = 0; + + if (buffer.Length == 0) + { + return false; + } + + buffer[i++] = 0; + + if (i == buffer.Length) + { + return false; + } + + if (!EncodeString(name, buffer.Slice(i), out int nameLength, lowercase: true)) + { + return false; + } + + i += nameLength; + + if (i >= buffer.Length) + { + return false; + } + + if (!EncodeString(value, buffer.Slice(i), out int valueLength, lowercase: false)) + { + return false; + } + + i += valueLength; + + length = i; + return true; + } + + private bool EncodeString(string value, Span<byte> destination, out int bytesWritten, bool lowercase) + { + // From https://tools.ietf.org/html/rfc7541#section-5.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | H | String Length (7+) | + // +---+---------------------------+ + // | String Data (Length octets) | + // +-------------------------------+ + const int toLowerMask = 0x20; + + if (destination.Length != 0) + { + destination[0] = 0; // TODO: Use Huffman encoding + if (IntegerEncoder.Encode(value.Length, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + destination = destination.Slice(integerLength); + if (value.Length <= destination.Length) + { + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + destination[i] = (byte)(lowercase && (uint)(c - 'A') <= ('Z' - 'A') ? c | toLowerMask : c); + } + + bytesWritten = integerLength + value.Length; + return true; + } + } + } + + bytesWritten = 0; + return false; + } + + // Things we should add: + // * Huffman encoding + // + // Things we should consider adding: + // * Dynamic table encoding: + // This would make the encoder stateful, which complicates things significantly. + // Additionally, it's not clear exactly what strings we would add to the dynamic table + // without some additional guidance from the user about this. + // So for now, don't do dynamic encoding. + + /// <summary>Encodes an "Indexed Header Field".</summary> + public static bool EncodeIndexedHeaderField(int index, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-6.1 + // ---------------------------------------------------- + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 1 | Index (7+) | + // +---+---------------------------+ + + if (destination.Length != 0) + { + destination[0] = 0x80; + return IntegerEncoder.Encode(index, 7, destination, out bytesWritten); + } + + bytesWritten = 0; + return false; + } + + /// <summary>Encodes a "Literal Header Field without Indexing".</summary> + public static bool EncodeLiteralHeaderFieldWithoutIndexing(int index, string value, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-6.2.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | Index (4+) | + // +---+---+-----------------------+ + // | H | Value Length (7+) | + // +---+---------------------------+ + // | Value String (Length octets) | + // +-------------------------------+ + + if ((uint)destination.Length >= 2) + { + destination[0] = 0; + if (IntegerEncoder.Encode(index, 4, destination, out int indexLength)) + { + Debug.Assert(indexLength >= 1); + if (EncodeStringLiteral(value, destination.Slice(indexLength), out int nameLength)) + { + bytesWritten = indexLength + nameLength; + return true; + } + } + } + + bytesWritten = 0; + return false; + } + + /// <summary> + /// Encodes a "Literal Header Field without Indexing", but only the index portion; + /// a subsequent call to <see cref="EncodeStringLiteral"/> must be used to encode the associated value. + /// </summary> + public static bool EncodeLiteralHeaderFieldWithoutIndexing(int index, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-6.2.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | Index (4+) | + // +---+---+-----------------------+ + // + // ... expected after this: + // + // | H | Value Length (7+) | + // +---+---------------------------+ + // | Value String (Length octets) | + // +-------------------------------+ + + if ((uint)destination.Length != 0) + { + destination[0] = 0; + if (IntegerEncoder.Encode(index, 4, destination, out int indexLength)) + { + Debug.Assert(indexLength >= 1); + bytesWritten = indexLength; + return true; + } + } + + bytesWritten = 0; + return false; + } + + /// <summary>Encodes a "Literal Header Field without Indexing - New Name".</summary> + public static bool EncodeLiteralHeaderFieldWithoutIndexingNewName(string name, ReadOnlySpan<string> values, string separator, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-6.2.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | 0 | + // +---+---+-----------------------+ + // | H | Name Length (7+) | + // +---+---------------------------+ + // | Name String (Length octets) | + // +---+---------------------------+ + // | H | Value Length (7+) | + // +---+---------------------------+ + // | Value String (Length octets) | + // +-------------------------------+ + + if ((uint)destination.Length >= 3) + { + destination[0] = 0; + if (EncodeLiteralHeaderName(name, destination.Slice(1), out int nameLength) && + EncodeStringLiterals(values, separator, destination.Slice(1 + nameLength), out int valueLength)) + { + bytesWritten = 1 + nameLength + valueLength; + return true; + } + } + + bytesWritten = 0; + return false; + } + + /// <summary> + /// Encodes a "Literal Header Field without Indexing - New Name", but only the name portion; + /// a subsequent call to <see cref="EncodeStringLiteral"/> must be used to encode the associated value. + /// </summary> + public static bool EncodeLiteralHeaderFieldWithoutIndexingNewName(string name, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-6.2.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | 0 | 0 | 0 | 0 | 0 | + // +---+---+-----------------------+ + // | H | Name Length (7+) | + // +---+---------------------------+ + // | Name String (Length octets) | + // +---+---------------------------+ + // + // ... expected after this: + // + // | H | Value Length (7+) | + // +---+---------------------------+ + // | Value String (Length octets) | + // +-------------------------------+ + + if ((uint)destination.Length >= 2) + { + destination[0] = 0; + if (EncodeLiteralHeaderName(name, destination.Slice(1), out int nameLength)) + { + bytesWritten = 1 + nameLength; + return true; + } + } + + bytesWritten = 0; + return false; + } + + private static bool EncodeLiteralHeaderName(string value, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-5.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | H | String Length (7+) | + // +---+---------------------------+ + // | String Data (Length octets) | + // +-------------------------------+ + + if (destination.Length != 0) + { + destination[0] = 0; // TODO: Use Huffman encoding + if (IntegerEncoder.Encode(value.Length, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + destination = destination.Slice(integerLength); + if (value.Length <= destination.Length) + { + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + destination[i] = (byte)((uint)(c - 'A') <= ('Z' - 'A') ? c | 0x20 : c); + } + + bytesWritten = integerLength + value.Length; + return true; + } + } + } + + bytesWritten = 0; + return false; + } + + private static bool EncodeStringLiteralValue(string value, Span<byte> destination, out int bytesWritten) + { + if (value.Length <= destination.Length) + { + for (int i = 0; i < value.Length; i++) + { + char c = value[i]; + if ((c & 0xFF80) != 0) + { + throw new HttpRequestException(SR.net_http_request_invalid_char_encoding); + } + + destination[i] = (byte)c; + } + + bytesWritten = value.Length; + return true; + } + + bytesWritten = 0; + return false; + } + + public static bool EncodeStringLiteral(string value, Span<byte> destination, out int bytesWritten) + { + // From https://tools.ietf.org/html/rfc7541#section-5.2 + // ------------------------------------------------------ + // 0 1 2 3 4 5 6 7 + // +---+---+---+---+---+---+---+---+ + // | H | String Length (7+) | + // +---+---------------------------+ + // | String Data (Length octets) | + // +-------------------------------+ + + if (destination.Length != 0) + { + destination[0] = 0; // TODO: Use Huffman encoding + if (IntegerEncoder.Encode(value.Length, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + if (EncodeStringLiteralValue(value, destination.Slice(integerLength), out int valueLength)) + { + bytesWritten = integerLength + valueLength; + return true; + } + } + } + + bytesWritten = 0; + return false; + } + + public static bool EncodeStringLiterals(ReadOnlySpan<string> values, string separator, Span<byte> destination, out int bytesWritten) + { + bytesWritten = 0; + + if (values.Length == 0) + { + return EncodeStringLiteral("", destination, out bytesWritten); + } + else if (values.Length == 1) + { + return EncodeStringLiteral(values[0], destination, out bytesWritten); + } + + if (destination.Length != 0) + { + int valueLength = 0; + + // Calculate length of all parts and separators. + foreach (string part in values) + { + valueLength = checked((int)(valueLength + part.Length)); + } + + valueLength = checked((int)(valueLength + (values.Length - 1) * separator.Length)); + + destination[0] = 0; + if (IntegerEncoder.Encode(valueLength, 7, destination, out int integerLength)) + { + Debug.Assert(integerLength >= 1); + + int encodedLength = 0; + for (int j = 0; j < values.Length; j++) + { + if (j != 0 && !EncodeStringLiteralValue(separator, destination.Slice(integerLength), out encodedLength)) + { + return false; + } + + integerLength += encodedLength; + + if (!EncodeStringLiteralValue(values[j], destination.Slice(integerLength), out encodedLength)) + { + return false; + } + + integerLength += encodedLength; + } + + bytesWritten = integerLength; + return true; + } + } + + return false; + } + + /// <summary> + /// Encodes a "Literal Header Field without Indexing" to a new array, but only the index portion; + /// a subsequent call to <see cref="EncodeStringLiteral"/> must be used to encode the associated value. + /// </summary> + public static byte[] EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(int index) + { + Span<byte> span = stackalloc byte[256]; + bool success = EncodeLiteralHeaderFieldWithoutIndexing(index, span, out int length); + Debug.Assert(success, $"Stack-allocated space was too small for index '{index}'."); + return span.Slice(0, length).ToArray(); + } + + /// <summary> + /// Encodes a "Literal Header Field without Indexing - New Name" to a new array, but only the name portion; + /// a subsequent call to <see cref="EncodeStringLiteral"/> must be used to encode the associated value. + /// </summary> + public static byte[] EncodeLiteralHeaderFieldWithoutIndexingNewNameToAllocatedArray(string name) + { + Span<byte> span = stackalloc byte[256]; + bool success = EncodeLiteralHeaderFieldWithoutIndexingNewName(name, span, out int length); + Debug.Assert(success, $"Stack-allocated space was too small for \"{name}\"."); + return span.Slice(0, length).ToArray(); + } + + /// <summary>Encodes a "Literal Header Field without Indexing" to a new array.</summary> + public static byte[] EncodeLiteralHeaderFieldWithoutIndexingToAllocatedArray(int index, string value) + { + Span<byte> span = +#if DEBUG + stackalloc byte[4]; // to validate growth algorithm +#else + stackalloc byte[512]; +#endif + while (true) + { + if (EncodeLiteralHeaderFieldWithoutIndexing(index, value, span, out int length)) + { + return span.Slice(0, length).ToArray(); + } + + // This is a rare path, only used once per HTTP/2 connection and only + // for very long host names. Just allocate rather than complicate + // the code with ArrayPool usage. In practice we should never hit this, + // as hostnames should be <= 255 characters. + span = new byte[span.Length * 2]; + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackEncodingException.cs b/src/Shared/Http2/Hpack/HPackEncodingException.cs similarity index 53% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackEncodingException.cs rename to src/Shared/Http2/Hpack/HPackEncodingException.cs index 6911754476..397b313191 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackEncodingException.cs +++ b/src/Shared/Http2/Hpack/HPackEncodingException.cs @@ -1,16 +1,20 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. -using System; - -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack +namespace System.Net.Http.HPack { internal sealed class HPackEncodingException : Exception { + public HPackEncodingException() + { + } + public HPackEncodingException(string message) : base(message) { } + public HPackEncodingException(string message, Exception innerException) : base(message, innerException) { diff --git a/src/Shared/Http2/Hpack/HeaderField.cs b/src/Shared/Http2/Hpack/HeaderField.cs new file mode 100644 index 0000000000..1eba82412d --- /dev/null +++ b/src/Shared/Http2/Hpack/HeaderField.cs @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Diagnostics; +using System.Text; + +namespace System.Net.Http.HPack +{ + internal readonly struct HeaderField + { + // http://httpwg.org/specs/rfc7541.html#rfc.section.4.1 + public const int RfcOverhead = 32; + + public HeaderField(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) + { + Debug.Assert(name.Length > 0); + + // TODO: We're allocating here on every new table entry. + // That means a poorly-behaved server could cause us to allocate repeatedly. + // We should revisit our allocation strategy here so we don't need to allocate per entry + // and we have a cap to how much allocation can happen per dynamic table + // (without limiting the number of table entries a server can provide within the table size limit). + Name = new byte[name.Length]; + name.CopyTo(Name); + + Value = new byte[value.Length]; + value.CopyTo(Value); + } + + public byte[] Name { get; } + + public byte[] Value { get; } + + public int Length => GetLength(Name.Length, Value.Length); + + public static int GetLength(int nameLength, int valueLength) => nameLength + valueLength + RfcOverhead; + + public override string ToString() + { + if (Name != null) + { + return Encoding.ASCII.GetString(Name) + ": " + Encoding.ASCII.GetString(Value); + } + else + { + return "<empty>"; + } + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/Huffman.cs b/src/Shared/Http2/Hpack/Huffman.cs similarity index 93% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPack/Huffman.cs rename to src/Shared/Http2/Hpack/Huffman.cs index fed5481d30..1cfc8e7d5d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/Huffman.cs +++ b/src/Shared/Http2/Hpack/Huffman.cs @@ -1,9 +1,10 @@ // 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. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. -using System; +using System.Diagnostics; -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack +namespace System.Net.Http.HPack { internal class Huffman { @@ -303,25 +304,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack /// Decodes a Huffman encoded string from a byte array. /// </summary> /// <param name="src">The source byte array containing the encoded data.</param> - /// <param name="dst">The destination byte array to store the decoded data.</param> + /// <param name="dstArray">The destination byte array to store the decoded data. This may grow if its size is insufficient.</param> /// <returns>The number of decoded symbols.</returns> - public static int Decode(ReadOnlySpan<byte> src, Span<byte> dst) + public static int Decode(ReadOnlySpan<byte> src, ref byte[] dstArray) { - var i = 0; - var j = 0; - var lastDecodedBits = 0; + Span<byte> dst = dstArray; + Debug.Assert(dst != null && dst.Length > 0); + + int i = 0; + int j = 0; + int lastDecodedBits = 0; while (i < src.Length) { // Note that if lastDecodeBits is 3 or more, then we will only get 5 bits (or less) // from src[i]. Thus we need to read 5 bytes here to ensure that we always have // at least 30 bits available for decoding. - var next = (uint)(src[i] << 24 + lastDecodedBits); + // TODO ISSUE 31751: Rework this as part of Huffman perf improvements + uint next = (uint)(src[i] << 24 + lastDecodedBits); next |= (i + 1 < src.Length ? (uint)(src[i + 1] << 16 + lastDecodedBits) : 0); next |= (i + 2 < src.Length ? (uint)(src[i + 2] << 8 + lastDecodedBits) : 0); next |= (i + 3 < src.Length ? (uint)(src[i + 3] << lastDecodedBits) : 0); next |= (i + 4 < src.Length ? (uint)(src[i + 4] >> (8 - lastDecodedBits)) : 0); - var ones = (uint)(int.MinValue >> (8 - lastDecodedBits - 1)); + uint ones = (uint)(int.MinValue >> (8 - lastDecodedBits - 1)); if (i == src.Length - 1 && lastDecodedBits > 0 && (next & ones) == ones) { // The remaining 7 or less bits are all 1, which is padding. @@ -334,24 +339,25 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack // The longest possible symbol size is 30 bits. If we're at the last 4 bytes // of the input, we need to make sure we pass the correct number of valid bits // left, otherwise the trailing 0s in next may form a valid symbol. - var validBits = Math.Min(30, (8 - lastDecodedBits) + (src.Length - i - 1) * 8); - var ch = DecodeValue(next, validBits, out var decodedBits); + int validBits = Math.Min(30, (8 - lastDecodedBits) + (src.Length - i - 1) * 8); + int ch = DecodeValue(next, validBits, out int decodedBits); if (ch == -1) { // No valid symbol could be decoded with the bits in next - throw new HuffmanDecodingException(CoreStrings.HPackHuffmanErrorIncomplete); + throw new HuffmanDecodingException(SR.net_http_hpack_huffman_decode_failed); } else if (ch == 256) { // A Huffman-encoded string literal containing the EOS symbol MUST be treated as a decoding error. // http://httpwg.org/specs/rfc7541.html#rfc.section.5.2 - throw new HuffmanDecodingException(CoreStrings.HPackHuffmanErrorEOS); + throw new HuffmanDecodingException(SR.net_http_hpack_huffman_decode_failed); } if (j == dst.Length) { - throw new HuffmanDecodingException(CoreStrings.HPackHuffmanErrorDestinationTooSmall); + Array.Resize(ref dstArray, dst.Length * 2); + dst = dstArray; } dst[j++] = (byte)ch; @@ -398,11 +404,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack // symbol in the list of values associated with bit length b in the decoding table by indexing it // with codeMax - v. - var codeMax = 0; + int codeMax = 0; - for (var i = 0; i < _decodingTable.Length && _decodingTable[i].codeLength <= validBits; i++) + for (int i = 0; i < _decodingTable.Length && _decodingTable[i].codeLength <= validBits; i++) { - var (codeLength, codes) = _decodingTable[i]; + (int codeLength, int[] codes) = _decodingTable[i]; if (i > 0) { @@ -411,8 +417,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack codeMax += codes.Length; - var mask = int.MinValue >> (codeLength - 1); - var masked = (data & mask) >> (32 - codeLength); + int mask = int.MinValue >> (codeLength - 1); + long masked = (data & mask) >> (32 - codeLength); if (masked < codeMax) { diff --git a/src/Shared/Http2/Hpack/HuffmanDecodingException.cs b/src/Shared/Http2/Hpack/HuffmanDecodingException.cs new file mode 100644 index 0000000000..64352e9535 --- /dev/null +++ b/src/Shared/Http2/Hpack/HuffmanDecodingException.cs @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Runtime.Serialization; + +namespace System.Net.Http.HPack +{ + // TODO: Should this be public? + [Serializable] + internal class HuffmanDecodingException : Exception, ISerializable + { + public HuffmanDecodingException() + { + } + + public HuffmanDecodingException(string message) + : base(message) + { + } + + protected HuffmanDecodingException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + base.GetObjectData(serializationInfo, streamingContext); + } + + public override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext) + { + base.GetObjectData(serializationInfo, streamingContext); + } + } +} diff --git a/src/Shared/Http2/Hpack/IntegerDecoder.cs b/src/Shared/Http2/Hpack/IntegerDecoder.cs new file mode 100644 index 0000000000..dafa6c08b4 --- /dev/null +++ b/src/Shared/Http2/Hpack/IntegerDecoder.cs @@ -0,0 +1,103 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Diagnostics; +using System.Numerics; + +namespace System.Net.Http.HPack +{ + internal class IntegerDecoder + { + private int _i; + private int _m; + + /// <summary> + /// Decodes the first byte of the integer. + /// </summary> + /// <param name="b"> + /// The first byte of the variable-length encoded integer. + /// </param> + /// <param name="prefixLength"> + /// The number of lower bits in this prefix byte that the + /// integer has been encoded into. Must be between 1 and 8. + /// Upper bits must be zero. + /// </param> + /// <param name="result"> + /// If decoded successfully, contains the decoded integer. + /// </param> + /// <returns> + /// If the integer has been fully decoded, true. + /// Otherwise, false -- <see cref="TryDecode(byte, out int)"/> must be called on subsequent bytes. + /// </returns> + /// <remarks> + /// The term "prefix" can be confusing. From the HPACK spec: + /// An integer is represented in two parts: a prefix that fills the current octet and an + /// optional list of octets that are used if the integer value does not fit within the prefix. + /// </remarks> + public bool BeginTryDecode(byte b, int prefixLength, out int result) + { + Debug.Assert(prefixLength >= 1 && prefixLength <= 8); + Debug.Assert((b & ~((1 << prefixLength) - 1)) == 0, "bits other than prefix data must be set to 0."); + + if (b < ((1 << prefixLength) - 1)) + { + result = b; + return true; + } + + _i = b; + _m = 0; + result = 0; + return false; + } + + /// <summary> + /// Decodes subsequent bytes of an integer. + /// </summary> + /// <param name="b">The next byte.</param> + /// <param name="result"> + /// If decoded successfully, contains the decoded integer. + /// </param> + /// <returns>If the integer has been fully decoded, true. Otherwise, false -- <see cref="TryDecode(byte, out int)"/> must be called on subsequent bytes.</returns> + public bool TryDecode(byte b, out int result) + { + // Check if shifting b by _m would result in > 31 bits. + // No masking is required: if the 8th bit is set, it indicates there is a + // bit set in a future byte, so it is fine to check that here as if it were + // bit 0 on the next byte. + // This is a simplified form of: + // int additionalBitsRequired = 32 - BitOperations.LeadingZeroCount((uint)b); + // if (_m + additionalBitsRequired > 31) + if (BitOperations.LeadingZeroCount((uint)b) <= _m) + { + throw new HPackDecodingException(SR.net_http_hpack_bad_integer); + } + + _i = _i + ((b & 0x7f) << _m); + + // If the addition overflowed, the result will be negative. + if (_i < 0) + { + throw new HPackDecodingException(SR.net_http_hpack_bad_integer); + } + + _m = _m + 7; + + if ((b & 128) == 0) + { + if (b == 0 && _m / 7 > 1) + { + // Do not accept overlong encodings. + throw new HPackDecodingException(SR.net_http_hpack_bad_integer); + } + + result = _i; + return true; + } + + result = 0; + return false; + } + } +} diff --git a/src/Shared/Http2/Hpack/IntegerEncoder.cs b/src/Shared/Http2/Hpack/IntegerEncoder.cs new file mode 100644 index 0000000000..b98bfd3c75 --- /dev/null +++ b/src/Shared/Http2/Hpack/IntegerEncoder.cs @@ -0,0 +1,73 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Diagnostics; + +namespace System.Net.Http.HPack +{ + internal static class IntegerEncoder + { + /// <summary> + /// Encodes an integer into one or more bytes. + /// </summary> + /// <param name="value">The value to encode. Must not be negative.</param> + /// <param name="numBits">The length of the prefix, in bits, to encode <paramref name="value"/> within. Must be between 1 and 8.</param> + /// <param name="destination">The destination span to encode <paramref name="value"/> to.</param> + /// <param name="bytesWritten">The number of bytes used to encode <paramref name="value"/>.</param> + /// <returns>If <paramref name="destination"/> had enough storage to encode <paramref name="value"/>, true. Otherwise, false.</returns> + public static bool Encode(int value, int numBits, Span<byte> destination, out int bytesWritten) + { + Debug.Assert(value >= 0); + Debug.Assert(numBits >= 1 && numBits <= 8); + + if (destination.Length == 0) + { + bytesWritten = 0; + return false; + } + + destination[0] &= MaskHigh(8 - numBits); + + if (value < (1 << numBits) - 1) + { + destination[0] |= (byte)value; + + bytesWritten = 1; + return true; + } + else + { + destination[0] |= (byte)((1 << numBits) - 1); + + if (1 == destination.Length) + { + bytesWritten = 0; + return false; + } + + value = value - ((1 << numBits) - 1); + int i = 1; + + while (value >= 128) + { + destination[i++] = (byte)(value % 128 + 128); + + if (i >= destination.Length) + { + bytesWritten = 0; + return false; + } + + value = value / 128; + } + destination[i++] = (byte)value; + + bytesWritten = i; + return true; + } + } + + private static byte MaskHigh(int n) => (byte)(sbyte.MinValue >> (n - 1)); + } +} diff --git a/src/Shared/Http2/Hpack/StaticTable.cs b/src/Shared/Http2/Hpack/StaticTable.cs new file mode 100644 index 0000000000..79090d8495 --- /dev/null +++ b/src/Shared/Http2/Hpack/StaticTable.cs @@ -0,0 +1,159 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Collections.Generic; +using System.Text; + +namespace System.Net.Http.HPack +{ + internal static class StaticTable + { + // Index of status code into s_staticDecoderTable + private static readonly Dictionary<int, int> s_statusIndex = new Dictionary<int, int> + { + [200] = 8, + [204] = 9, + [206] = 10, + [304] = 11, + [400] = 12, + [404] = 13, + [500] = 14, + }; + + public static int Count => s_staticDecoderTable.Length; + + public static HeaderField Get(int index) => s_staticDecoderTable[index]; + + public static IReadOnlyDictionary<int, int> StatusIndex => s_statusIndex; + + private static readonly HeaderField[] s_staticDecoderTable = new HeaderField[] + { + CreateHeaderField(":authority", ""), + CreateHeaderField(":method", "GET"), + CreateHeaderField(":method", "POST"), + CreateHeaderField(":path", "/"), + CreateHeaderField(":path", "/index.html"), + CreateHeaderField(":scheme", "http"), + CreateHeaderField(":scheme", "https"), + CreateHeaderField(":status", "200"), + CreateHeaderField(":status", "204"), + CreateHeaderField(":status", "206"), + CreateHeaderField(":status", "304"), + CreateHeaderField(":status", "400"), + CreateHeaderField(":status", "404"), + CreateHeaderField(":status", "500"), + CreateHeaderField("accept-charset", ""), + CreateHeaderField("accept-encoding", "gzip, deflate"), + CreateHeaderField("accept-language", ""), + CreateHeaderField("accept-ranges", ""), + CreateHeaderField("accept", ""), + CreateHeaderField("access-control-allow-origin", ""), + CreateHeaderField("age", ""), + CreateHeaderField("allow", ""), + CreateHeaderField("authorization", ""), + CreateHeaderField("cache-control", ""), + CreateHeaderField("content-disposition", ""), + CreateHeaderField("content-encoding", ""), + CreateHeaderField("content-language", ""), + CreateHeaderField("content-length", ""), + CreateHeaderField("content-location", ""), + CreateHeaderField("content-range", ""), + CreateHeaderField("content-type", ""), + CreateHeaderField("cookie", ""), + CreateHeaderField("date", ""), + CreateHeaderField("etag", ""), + CreateHeaderField("expect", ""), + CreateHeaderField("expires", ""), + CreateHeaderField("from", ""), + CreateHeaderField("host", ""), + CreateHeaderField("if-match", ""), + CreateHeaderField("if-modified-since", ""), + CreateHeaderField("if-none-match", ""), + CreateHeaderField("if-range", ""), + CreateHeaderField("if-unmodified-since", ""), + CreateHeaderField("last-modified", ""), + CreateHeaderField("link", ""), + CreateHeaderField("location", ""), + CreateHeaderField("max-forwards", ""), + CreateHeaderField("proxy-authenticate", ""), + CreateHeaderField("proxy-authorization", ""), + CreateHeaderField("range", ""), + CreateHeaderField("referer", ""), + CreateHeaderField("refresh", ""), + CreateHeaderField("retry-after", ""), + CreateHeaderField("server", ""), + CreateHeaderField("set-cookie", ""), + CreateHeaderField("strict-transport-security", ""), + CreateHeaderField("transfer-encoding", ""), + CreateHeaderField("user-agent", ""), + CreateHeaderField("vary", ""), + CreateHeaderField("via", ""), + CreateHeaderField("www-authenticate", "") + }; + + // TODO: The HeaderField constructor will allocate and copy again. We should avoid this. + // Tackle as part of header table allocation strategy in general (see note in HeaderField constructor). + + private static HeaderField CreateHeaderField(string name, string value) => + new HeaderField( + Encoding.ASCII.GetBytes(name), + value.Length != 0 ? Encoding.ASCII.GetBytes(value) : Array.Empty<byte>()); + + // Values for encoding. + // Unused values are omitted. + public const int Authority = 1; + public const int MethodGet = 2; + public const int MethodPost = 3; + public const int PathSlash = 4; + public const int SchemeHttp = 6; + public const int SchemeHttps = 7; + public const int AcceptCharset = 15; + public const int AcceptEncoding = 16; + public const int AcceptLanguage = 17; + public const int AcceptRanges = 18; + public const int Accept = 19; + public const int AccessControlAllowOrigin = 20; + public const int Age = 21; + public const int Allow = 22; + public const int Authorization = 23; + public const int CacheControl = 24; + public const int ContentDisposition = 25; + public const int ContentEncoding = 26; + public const int ContentLanguage = 27; + public const int ContentLength = 28; + public const int ContentLocation = 29; + public const int ContentRange = 30; + public const int ContentType = 31; + public const int Cookie = 32; + public const int Date = 33; + public const int ETag = 34; + public const int Expect = 35; + public const int Expires = 36; + public const int From = 37; + public const int Host = 38; + public const int IfMatch = 39; + public const int IfModifiedSince = 40; + public const int IfNoneMatch = 41; + public const int IfRange = 42; + public const int IfUnmodifiedSince = 43; + public const int LastModified = 44; + public const int Link = 45; + public const int Location = 46; + public const int MaxForwards = 47; + public const int ProxyAuthenticate = 48; + public const int ProxyAuthorization = 49; + public const int Range = 50; + public const int Referer = 51; + public const int Refresh = 52; + public const int RetryAfter = 53; + public const int Server = 54; + public const int SetCookie = 55; + public const int StrictTransportSecurity = 56; + public const int TransferEncoding = 57; + public const int UserAgent = 58; + public const int Vary = 59; + public const int Via = 60; + public const int WwwAuthenticate = 61; + } +} diff --git a/src/Shared/Http2/Hpack/StatusCodes.cs b/src/Shared/Http2/Hpack/StatusCodes.cs new file mode 100644 index 0000000000..f302e7339b --- /dev/null +++ b/src/Shared/Http2/Hpack/StatusCodes.cs @@ -0,0 +1,220 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Globalization; +using System.Text; + +namespace System.Net.Http.HPack +{ + internal static class StatusCodes + { + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + + private static ReadOnlySpan<byte> BytesStatus100 => new byte[] { (byte)'1', (byte)'0', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus101 => new byte[] { (byte)'1', (byte)'0', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus102 => new byte[] { (byte)'1', (byte)'0', (byte)'2' }; + + private static ReadOnlySpan<byte> BytesStatus200 => new byte[] { (byte)'2', (byte)'0', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus201 => new byte[] { (byte)'2', (byte)'0', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus202 => new byte[] { (byte)'2', (byte)'0', (byte)'2' }; + private static ReadOnlySpan<byte> BytesStatus203 => new byte[] { (byte)'2', (byte)'0', (byte)'3' }; + private static ReadOnlySpan<byte> BytesStatus204 => new byte[] { (byte)'2', (byte)'0', (byte)'4' }; + private static ReadOnlySpan<byte> BytesStatus205 => new byte[] { (byte)'2', (byte)'0', (byte)'5' }; + private static ReadOnlySpan<byte> BytesStatus206 => new byte[] { (byte)'2', (byte)'0', (byte)'6' }; + private static ReadOnlySpan<byte> BytesStatus207 => new byte[] { (byte)'2', (byte)'0', (byte)'7' }; + private static ReadOnlySpan<byte> BytesStatus208 => new byte[] { (byte)'2', (byte)'0', (byte)'8' }; + private static ReadOnlySpan<byte> BytesStatus226 => new byte[] { (byte)'2', (byte)'2', (byte)'6' }; + + private static ReadOnlySpan<byte> BytesStatus300 => new byte[] { (byte)'3', (byte)'0', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus301 => new byte[] { (byte)'3', (byte)'0', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus302 => new byte[] { (byte)'3', (byte)'0', (byte)'2' }; + private static ReadOnlySpan<byte> BytesStatus303 => new byte[] { (byte)'3', (byte)'0', (byte)'3' }; + private static ReadOnlySpan<byte> BytesStatus304 => new byte[] { (byte)'3', (byte)'0', (byte)'4' }; + private static ReadOnlySpan<byte> BytesStatus305 => new byte[] { (byte)'3', (byte)'0', (byte)'5' }; + private static ReadOnlySpan<byte> BytesStatus306 => new byte[] { (byte)'3', (byte)'0', (byte)'6' }; + private static ReadOnlySpan<byte> BytesStatus307 => new byte[] { (byte)'3', (byte)'0', (byte)'7' }; + private static ReadOnlySpan<byte> BytesStatus308 => new byte[] { (byte)'3', (byte)'0', (byte)'8' }; + + private static ReadOnlySpan<byte> BytesStatus400 => new byte[] { (byte)'4', (byte)'0', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus401 => new byte[] { (byte)'4', (byte)'0', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus402 => new byte[] { (byte)'4', (byte)'0', (byte)'2' }; + private static ReadOnlySpan<byte> BytesStatus403 => new byte[] { (byte)'4', (byte)'0', (byte)'3' }; + private static ReadOnlySpan<byte> BytesStatus404 => new byte[] { (byte)'4', (byte)'0', (byte)'4' }; + private static ReadOnlySpan<byte> BytesStatus405 => new byte[] { (byte)'4', (byte)'0', (byte)'5' }; + private static ReadOnlySpan<byte> BytesStatus406 => new byte[] { (byte)'4', (byte)'0', (byte)'6' }; + private static ReadOnlySpan<byte> BytesStatus407 => new byte[] { (byte)'4', (byte)'0', (byte)'7' }; + private static ReadOnlySpan<byte> BytesStatus408 => new byte[] { (byte)'4', (byte)'0', (byte)'8' }; + private static ReadOnlySpan<byte> BytesStatus409 => new byte[] { (byte)'4', (byte)'0', (byte)'9' }; + private static ReadOnlySpan<byte> BytesStatus410 => new byte[] { (byte)'4', (byte)'1', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus411 => new byte[] { (byte)'4', (byte)'1', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus412 => new byte[] { (byte)'4', (byte)'1', (byte)'2' }; + private static ReadOnlySpan<byte> BytesStatus413 => new byte[] { (byte)'4', (byte)'1', (byte)'3' }; + private static ReadOnlySpan<byte> BytesStatus414 => new byte[] { (byte)'4', (byte)'1', (byte)'4' }; + private static ReadOnlySpan<byte> BytesStatus415 => new byte[] { (byte)'4', (byte)'1', (byte)'5' }; + private static ReadOnlySpan<byte> BytesStatus416 => new byte[] { (byte)'4', (byte)'1', (byte)'6' }; + private static ReadOnlySpan<byte> BytesStatus417 => new byte[] { (byte)'4', (byte)'1', (byte)'7' }; + private static ReadOnlySpan<byte> BytesStatus418 => new byte[] { (byte)'4', (byte)'1', (byte)'8' }; + private static ReadOnlySpan<byte> BytesStatus419 => new byte[] { (byte)'4', (byte)'1', (byte)'9' }; + private static ReadOnlySpan<byte> BytesStatus421 => new byte[] { (byte)'4', (byte)'2', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus422 => new byte[] { (byte)'4', (byte)'2', (byte)'2' }; + private static ReadOnlySpan<byte> BytesStatus423 => new byte[] { (byte)'4', (byte)'2', (byte)'3' }; + private static ReadOnlySpan<byte> BytesStatus424 => new byte[] { (byte)'4', (byte)'2', (byte)'4' }; + private static ReadOnlySpan<byte> BytesStatus426 => new byte[] { (byte)'4', (byte)'2', (byte)'6' }; + private static ReadOnlySpan<byte> BytesStatus428 => new byte[] { (byte)'4', (byte)'2', (byte)'8' }; + private static ReadOnlySpan<byte> BytesStatus429 => new byte[] { (byte)'4', (byte)'2', (byte)'9' }; + private static ReadOnlySpan<byte> BytesStatus431 => new byte[] { (byte)'4', (byte)'3', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus451 => new byte[] { (byte)'4', (byte)'5', (byte)'1' }; + + private static ReadOnlySpan<byte> BytesStatus500 => new byte[] { (byte)'5', (byte)'0', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus501 => new byte[] { (byte)'5', (byte)'0', (byte)'1' }; + private static ReadOnlySpan<byte> BytesStatus502 => new byte[] { (byte)'5', (byte)'0', (byte)'2' }; + private static ReadOnlySpan<byte> BytesStatus503 => new byte[] { (byte)'5', (byte)'0', (byte)'3' }; + private static ReadOnlySpan<byte> BytesStatus504 => new byte[] { (byte)'5', (byte)'0', (byte)'4' }; + private static ReadOnlySpan<byte> BytesStatus505 => new byte[] { (byte)'5', (byte)'0', (byte)'5' }; + private static ReadOnlySpan<byte> BytesStatus506 => new byte[] { (byte)'5', (byte)'0', (byte)'6' }; + private static ReadOnlySpan<byte> BytesStatus507 => new byte[] { (byte)'5', (byte)'0', (byte)'7' }; + private static ReadOnlySpan<byte> BytesStatus508 => new byte[] { (byte)'5', (byte)'0', (byte)'8' }; + private static ReadOnlySpan<byte> BytesStatus510 => new byte[] { (byte)'5', (byte)'1', (byte)'0' }; + private static ReadOnlySpan<byte> BytesStatus511 => new byte[] { (byte)'5', (byte)'1', (byte)'1' }; + + public static ReadOnlySpan<byte> ToStatusBytes(int statusCode) + { + switch (statusCode) + { + case (int)HttpStatusCode.Continue: + return BytesStatus100; + case (int)HttpStatusCode.SwitchingProtocols: + return BytesStatus101; + case (int)HttpStatusCode.Processing: + return BytesStatus102; + + case (int)HttpStatusCode.OK: + return BytesStatus200; + case (int)HttpStatusCode.Created: + return BytesStatus201; + case (int)HttpStatusCode.Accepted: + return BytesStatus202; + case (int)HttpStatusCode.NonAuthoritativeInformation: + return BytesStatus203; + case (int)HttpStatusCode.NoContent: + return BytesStatus204; + case (int)HttpStatusCode.ResetContent: + return BytesStatus205; + case (int)HttpStatusCode.PartialContent: + return BytesStatus206; + case (int)HttpStatusCode.MultiStatus: + return BytesStatus207; + case (int)HttpStatusCode.AlreadyReported: + return BytesStatus208; + case (int)HttpStatusCode.IMUsed: + return BytesStatus226; + + case (int)HttpStatusCode.MultipleChoices: + return BytesStatus300; + case (int)HttpStatusCode.MovedPermanently: + return BytesStatus301; + case (int)HttpStatusCode.Found: + return BytesStatus302; + case (int)HttpStatusCode.SeeOther: + return BytesStatus303; + case (int)HttpStatusCode.NotModified: + return BytesStatus304; + case (int)HttpStatusCode.UseProxy: + return BytesStatus305; + case (int)HttpStatusCode.Unused: + return BytesStatus306; + case (int)HttpStatusCode.TemporaryRedirect: + return BytesStatus307; + case (int)HttpStatusCode.PermanentRedirect: + return BytesStatus308; + + case (int)HttpStatusCode.BadRequest: + return BytesStatus400; + case (int)HttpStatusCode.Unauthorized: + return BytesStatus401; + case (int)HttpStatusCode.PaymentRequired: + return BytesStatus402; + case (int)HttpStatusCode.Forbidden: + return BytesStatus403; + case (int)HttpStatusCode.NotFound: + return BytesStatus404; + case (int)HttpStatusCode.MethodNotAllowed: + return BytesStatus405; + case (int)HttpStatusCode.NotAcceptable: + return BytesStatus406; + case (int)HttpStatusCode.ProxyAuthenticationRequired: + return BytesStatus407; + case (int)HttpStatusCode.RequestTimeout: + return BytesStatus408; + case (int)HttpStatusCode.Conflict: + return BytesStatus409; + case (int)HttpStatusCode.Gone: + return BytesStatus410; + case (int)HttpStatusCode.LengthRequired: + return BytesStatus411; + case (int)HttpStatusCode.PreconditionFailed: + return BytesStatus412; + case (int)HttpStatusCode.RequestEntityTooLarge: + return BytesStatus413; + case (int)HttpStatusCode.RequestUriTooLong: + return BytesStatus414; + case (int)HttpStatusCode.UnsupportedMediaType: + return BytesStatus415; + case (int)HttpStatusCode.RequestedRangeNotSatisfiable: + return BytesStatus416; + case (int)HttpStatusCode.ExpectationFailed: + return BytesStatus417; + case (int)418: + return BytesStatus418; + case (int)419: + return BytesStatus419; + case (int)HttpStatusCode.MisdirectedRequest: + return BytesStatus421; + case (int)HttpStatusCode.UnprocessableEntity: + return BytesStatus422; + case (int)HttpStatusCode.Locked: + return BytesStatus423; + case (int)HttpStatusCode.FailedDependency: + return BytesStatus424; + case (int)HttpStatusCode.UpgradeRequired: + return BytesStatus426; + case (int)HttpStatusCode.PreconditionRequired: + return BytesStatus428; + case (int)HttpStatusCode.TooManyRequests: + return BytesStatus429; + case (int)HttpStatusCode.RequestHeaderFieldsTooLarge: + return BytesStatus431; + case (int)HttpStatusCode.UnavailableForLegalReasons: + return BytesStatus451; + + case (int)HttpStatusCode.InternalServerError: + return BytesStatus500; + case (int)HttpStatusCode.NotImplemented: + return BytesStatus501; + case (int)HttpStatusCode.BadGateway: + return BytesStatus502; + case (int)HttpStatusCode.ServiceUnavailable: + return BytesStatus503; + case (int)HttpStatusCode.GatewayTimeout: + return BytesStatus504; + case (int)HttpStatusCode.HttpVersionNotSupported: + return BytesStatus505; + case (int)HttpStatusCode.VariantAlsoNegotiates: + return BytesStatus506; + case (int)HttpStatusCode.InsufficientStorage: + return BytesStatus507; + case (int)HttpStatusCode.LoopDetected: + return BytesStatus508; + case (int)HttpStatusCode.NotExtended: + return BytesStatus510; + case (int)HttpStatusCode.NetworkAuthenticationRequired: + return BytesStatus511; + + default: + return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture)); + + } + } + } +} diff --git a/src/Shared/Http2/IHttpHeadersHandler.cs b/src/Shared/Http2/IHttpHeadersHandler.cs new file mode 100644 index 0000000000..256dde1797 --- /dev/null +++ b/src/Shared/Http2/IHttpHeadersHandler.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if KESTREL +using System; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http +#else +namespace System.Net.Http +#endif +{ +#if KESTREL + public +#else + internal +#endif + interface IHttpHeadersHandler + { + void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value); + void OnHeadersComplete(bool endStream); + } +} diff --git a/src/Shared/Http2/ReadMe.SharedCode.md b/src/Shared/Http2/ReadMe.SharedCode.md new file mode 100644 index 0000000000..f5f420322d --- /dev/null +++ b/src/Shared/Http2/ReadMe.SharedCode.md @@ -0,0 +1,36 @@ +The code in this directory is shared between dotnet/runtime and dotnet/aspnetcore. This contains HTTP/2 protocol infrastructure such as an HPACK implementation. Any changes to this dir need to be checked into both repositories. + +dotnet/runtime code paths: +- runtime\src\libraries\Common\src\System\Net\Http\Http2 +- runtime\src\libraries\Common\tests\Tests\System\Net\Http2 +dotnet/aspnetcore code paths: +- AspNetCore\src\Shared\Http2 +- AspNetCore\src\Shared\test\Shared.Tests\Http2 + +## Copying code +To copy code from dotnet/runtime to dotnet/aspnetcore, set ASPNETCORE_REPO to the AspNetCore repo root and then run CopyToAspNetCore.cmd. +To copy code from dotnet/aspnetcore to dotnet/runtime, set RUNTIME_REPO to the runtime repo root and then run CopyToRuntime.cmd. + +## Building dotnet/runtime code: +- https://github.com/dotnet/runtime/blob/master/docs/libraries/building/windows-instructions.md +- https://github.com/dotnet/runtime/blob/master/docs/libraries/project-docs/developer-guide.md +- Run libraries.cmd from the root once: `PS D:\github\runtime> .\libraries.cmd` +- Build the individual projects: +- `PS D:\github\dotnet\src\libraries\Common\tests> dotnet msbuild /t:rebuild` +- `PS D:\github\dotnet\src\libraries\System.Net.Http\src> dotnet msbuild /t:rebuild` + +### Running dotnet/runtime tests: +- `PS D:\github\runtime\src\libraries\Common\tests> dotnet msbuild /t:rebuildandtest` +- `PS D:\github\runtime\src\libraries\System.Net.Http\tests\UnitTests> dotnet msbuild /t:rebuildandtest` + +## Building dotnet/aspnetcore code: +- https://github.com/dotnet/aspnetcore/blob/master/docs/BuildFromSource.md +- Run restore in the root once: `PS D:\github\AspNetCore> .\restore.cmd` +- Activate to use the repo local runtime: `PS D:\github\AspNetCore> . .\activate.ps1` +- Build the individual projects: +- `(AspNetCore) PS D:\github\AspNetCore\src\Shared\test\Shared.Tests> dotnet msbuild` +- `(AspNetCore) PS D:\github\AspNetCore\src\servers\Kestrel\core\src> dotnet msbuild` + +### Running dotnet/aspnetcore tests: +- `(AspNetCore) PS D:\github\AspNetCore\src\Shared\test\Shared.Tests> dotnet test` +- `(AspNetCore) PS D:\github\AspNetCore\src\servers\Kestrel\core\test> dotnet test` diff --git a/src/Shared/Http2/SR.cs b/src/Shared/Http2/SR.cs new file mode 100644 index 0000000000..7dd7cc5991 --- /dev/null +++ b/src/Shared/Http2/SR.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace System.Net.Http +{ + internal static partial class SR + { + // The resource generator used in AspNetCore does not create this method. This file fills in that functional gap + // so we don't have to modify the shared source. + internal static string Format(string resourceFormat, params object[] args) + { + if (args != null) + { + return string.Format(resourceFormat, args); + } + + return resourceFormat; + } + } +} diff --git a/src/Shared/Http2/SR.resx b/src/Shared/Http2/SR.resx new file mode 100644 index 0000000000..9e785e371f --- /dev/null +++ b/src/Shared/Http2/SR.resx @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="net_http_headers_exceeded_length" xml:space="preserve"> + <value>The HTTP headers length exceeded the set limit of {0} bytes.</value> + </data> + <data name="net_http_headers_invalid_header_name" xml:space="preserve"> + <value>The header name format is invalid.</value> + </data> + <data name="net_http_hpack_bad_integer" xml:space="preserve"> + <value>HPACK integer exceeds limits or has an overlong encoding.</value> + </data> + <data name="net_http_hpack_encode_failure" xml:space="preserve"> + <value>Failed to HPACK encode the headers.</value> + </data> + <data name="net_http_hpack_huffman_decode_failed" xml:space="preserve"> + <value>Huffman-coded literal string failed to decode.</value> + </data> + <data name="net_http_hpack_incomplete_header_block" xml:space="preserve"> + <value>Incomplete header block received.</value> + </data> + <data name="net_http_hpack_invalid_index" xml:space="preserve"> + <value>Invalid header index: {0} is outside of static table and no dynamic table entry found.</value> + </data> + <data name="net_http_hpack_large_table_size_update" xml:space="preserve"> + <value>A dynamic table size update of {0} octets is greater than the configured maximum size of {1} octets.</value> + </data> + <data name="net_http_hpack_late_dynamic_table_size_update" xml:space="preserve"> + <value>Dynamic table size update received after beginning of header block.</value> + </data> + <data name="net_http_hpack_unexpected_end" xml:space="preserve"> + <value>End of headers reached with incomplete token.</value> + </data> + <data name="net_http_invalid_header_name" xml:space="preserve"> + <value>Received an invalid header name: '{0}'.</value> + </data> + <data name="net_http_request_invalid_char_encoding" xml:space="preserve"> + <value>Request headers must contain only ASCII characters.</value> + </data> +</root> \ No newline at end of file diff --git a/src/Shared/Http2cat/Http2CatHostedService.cs b/src/Shared/Http2cat/Http2CatHostedService.cs new file mode 100644 index 0000000000..55e496fa10 --- /dev/null +++ b/src/Shared/Http2cat/Http2CatHostedService.cs @@ -0,0 +1,129 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO.Pipelines; +using System.Linq; +using System.Net; +using System.Net.Security; +using System.Security.Authentication; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Features; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; +using Microsoft.AspNetCore.Server.Kestrel.Https.Internal; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Microsoft.AspNetCore.Http2Cat +{ + internal class Http2CatHostedService : IHostedService + { + private readonly IConnectionFactory _connectionFactory; + private readonly ILogger<Http2CatHostedService> _logger; + private readonly CancellationTokenSource _stopTokenSource = new CancellationTokenSource(); + private Task _backgroundTask; + + public Http2CatHostedService(IConnectionFactory connectionFactory, ILogger<Http2CatHostedService> logger, + IOptions<Http2CatOptions> options, IHostApplicationLifetime hostApplicationLifetime) + { + _connectionFactory = connectionFactory; + _logger = logger; + HostApplicationLifetime = hostApplicationLifetime; + Options = options.Value; + } + + public IHostApplicationLifetime HostApplicationLifetime { get; } + private Http2CatOptions Options { get; } + + public Task StartAsync(CancellationToken cancellationToken) + { + _backgroundTask = RunAsync(); + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _stopTokenSource.Cancel(); + return _backgroundTask; + } + + private async Task RunAsync() + { + try + { + var address = BindingAddress.Parse(Options.Url); + + if (!IPAddress.TryParse(address.Host, out var ip)) + { + ip = Dns.GetHostEntry(address.Host).AddressList.First(); + } + + var endpoint = new IPEndPoint(ip, address.Port); + + _logger.LogInformation($"Connecting to '{endpoint}'."); + + await using var context = await _connectionFactory.ConnectAsync(endpoint); + + _logger.LogInformation($"Connected to '{endpoint}'."); + + var originalTransport = context.Transport; + IAsyncDisposable sslState = null; + if (address.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) + { + _logger.LogInformation("Starting TLS handshake."); + + var memoryPool = context.Features.Get<IMemoryPoolFeature>()?.MemoryPool; + var inputPipeOptions = new StreamPipeReaderOptions(memoryPool, memoryPool.GetMinimumSegmentSize(), memoryPool.GetMinimumAllocSize(), leaveOpen: true); + var outputPipeOptions = new StreamPipeWriterOptions(pool: memoryPool, leaveOpen: true); + + var sslDuplexPipe = new SslDuplexPipe(context.Transport, inputPipeOptions, outputPipeOptions); + var sslStream = sslDuplexPipe.Stream; + sslState = sslDuplexPipe; + + context.Transport = sslDuplexPipe; + + await sslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions + { + TargetHost = address.Host, + RemoteCertificateValidationCallback = (_, __, ___, ____) => true, + ApplicationProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http2 }, + EnabledSslProtocols = SslProtocols.Tls12, + }, CancellationToken.None); + + _logger.LogInformation($"TLS handshake completed successfully."); + } + + var http2Utilities = new Http2Utilities(context, _logger, _stopTokenSource.Token); + + try + { + await Options.Scenaro(http2Utilities); + } + catch (Exception ex) + { + _logger.LogError(ex, "App error"); + throw; + } + finally + { + // Unwind Https for shutdown. This must happen before the context goes out of scope or else DisposeAsync will never complete + context.Transport = originalTransport; + + if (sslState != null) + { + await sslState.DisposeAsync(); + } + } + } + finally + { + HostApplicationLifetime.StopApplication(); + } + } + } +} diff --git a/src/Shared/Http2cat/Http2CatIHostBuilderExtensions.cs b/src/Shared/Http2cat/Http2CatIHostBuilderExtensions.cs new file mode 100644 index 0000000000..9a37aafffa --- /dev/null +++ b/src/Shared/Http2cat/Http2CatIHostBuilderExtensions.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http2Cat; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.Extensions.Hosting +{ + internal static class Http2CatIHostBuilderExtensions + { + public static IHostBuilder UseHttp2Cat(this IHostBuilder hostBuilder, string address, Func<Http2Utilities, Task> scenario) + { + hostBuilder.ConfigureServices(services => + { + services.UseHttp2Cat(options => + { + options.Url = address; + options.Scenaro = scenario; + }); + }); + return hostBuilder; + } + } +} diff --git a/src/Shared/Http2cat/Http2CatIServiceCollectionExtensions.cs b/src/Shared/Http2cat/Http2CatIServiceCollectionExtensions.cs new file mode 100644 index 0000000000..52c6449225 --- /dev/null +++ b/src/Shared/Http2cat/Http2CatIServiceCollectionExtensions.cs @@ -0,0 +1,21 @@ +// 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 Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http2Cat; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Client; + +namespace Microsoft.Extensions.DependencyInjection +{ + internal static class Http2CatIServiceCollectionExtensions + { + public static IServiceCollection UseHttp2Cat(this IServiceCollection services, Action<Http2CatOptions> configureOptions) + { + services.AddSingleton<IConnectionFactory, SocketConnectionFactory>(); + services.AddHostedService<Http2CatHostedService>(); + services.Configure(configureOptions); + return services; + } + } +} diff --git a/src/Shared/Http2cat/Http2CatOptions.cs b/src/Shared/Http2cat/Http2CatOptions.cs new file mode 100644 index 0000000000..81e2b082f2 --- /dev/null +++ b/src/Shared/Http2cat/Http2CatOptions.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.Http2Cat +{ + internal class Http2CatOptions + { + public string Url { get; set; } + public Func<Http2Utilities, Task> Scenaro { get; set; } + } +} diff --git a/src/Shared/Http2cat/Http2CatReadMe.md b/src/Shared/Http2cat/Http2CatReadMe.md new file mode 100644 index 0000000000..1bd01c17ec --- /dev/null +++ b/src/Shared/Http2cat/Http2CatReadMe.md @@ -0,0 +1,7 @@ +## Http2Cat + +Http2Cat is a low level Http2 testing framework designed to excersize a server with frame level control. This can be useful for unit testing and compat testing. + +The framework is distributed as internal sources since it shares the basic building blocks from Kestrel's Http2 implementation (frames, enum flags, frame reading and writing, etc.). InternalsVisibleTo should not be used, any needed components should be moved to one of the shared code directories. + +This Http2Cat folder contains non-production code used in the test client. The shared production code is kept in separate folders. diff --git a/src/Shared/Http2cat/Http2Utilities.cs b/src/Shared/Http2cat/Http2Utilities.cs new file mode 100644 index 0000000000..14fe26a601 --- /dev/null +++ b/src/Shared/Http2cat/Http2Utilities.cs @@ -0,0 +1,1075 @@ +// 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.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.IO.Pipelines; +using System.Linq; +using System.Net.Http; +using System.Net.Http.HPack; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; +using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; + +namespace Microsoft.AspNetCore.Http2Cat +{ + internal class Http2Utilities : IHttpHeadersHandler + { + public static ReadOnlySpan<byte> ClientPreface => new byte[24] { (byte)'P', (byte)'R', (byte)'I', (byte)' ', (byte)'*', (byte)' ', (byte)'H', (byte)'T', (byte)'T', (byte)'P', (byte)'/', (byte)'2', (byte)'.', (byte)'0', (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n', (byte)'S', (byte)'M', (byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' }; + public static readonly int MaxRequestHeaderFieldSize = 16 * 1024; + public static readonly string FourKHeaderValue = new string('a', 4096); + private static readonly Encoding HeaderValueEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); + + public static readonly IEnumerable<KeyValuePair<string, string>> BrowserRequestHeaders = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "GET"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "https"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:443"), + new KeyValuePair<string, string>("user-agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"), + new KeyValuePair<string, string>("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"), + new KeyValuePair<string, string>("accept-language", "en-US,en;q=0.5"), + new KeyValuePair<string, string>("accept-encoding", "gzip, deflate, br"), + new KeyValuePair<string, string>("upgrade-insecure-requests", "1"), + }; + + public static readonly IEnumerable<KeyValuePair<string, string>> BrowserRequestHeadersHttp = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "GET"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "http"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"), + new KeyValuePair<string, string>("user-agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"), + new KeyValuePair<string, string>("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"), + new KeyValuePair<string, string>("accept-language", "en-US,en;q=0.5"), + new KeyValuePair<string, string>("accept-encoding", "gzip, deflate, br"), + new KeyValuePair<string, string>("upgrade-insecure-requests", "1"), + }; + + public static readonly IEnumerable<KeyValuePair<string, string>> PostRequestHeaders = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "POST"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "https"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"), + }; + + public static readonly IEnumerable<KeyValuePair<string, string>> ExpectContinueRequestHeaders = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "POST"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Authority, "127.0.0.1"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "https"), + new KeyValuePair<string, string>("expect", "100-continue"), + }; + + public static readonly IEnumerable<KeyValuePair<string, string>> RequestTrailers = new[] + { + new KeyValuePair<string, string>("trailer-one", "1"), + new KeyValuePair<string, string>("trailer-two", "2"), + }; + + public static readonly IEnumerable<KeyValuePair<string, string>> OneContinuationRequestHeaders = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "GET"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "https"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"), + new KeyValuePair<string, string>("a", FourKHeaderValue), + new KeyValuePair<string, string>("b", FourKHeaderValue), + new KeyValuePair<string, string>("c", FourKHeaderValue), + new KeyValuePair<string, string>("d", FourKHeaderValue) + }; + + public static readonly IEnumerable<KeyValuePair<string, string>> TwoContinuationsRequestHeaders = new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "GET"), + new KeyValuePair<string, string>(HeaderNames.Path, "/"), + new KeyValuePair<string, string>(HeaderNames.Scheme, "https"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"), + new KeyValuePair<string, string>("a", FourKHeaderValue), + new KeyValuePair<string, string>("b", FourKHeaderValue), + new KeyValuePair<string, string>("c", FourKHeaderValue), + new KeyValuePair<string, string>("d", FourKHeaderValue), + new KeyValuePair<string, string>("e", FourKHeaderValue), + new KeyValuePair<string, string>("f", FourKHeaderValue), + new KeyValuePair<string, string>("g", FourKHeaderValue), + }; + + public static IEnumerable<KeyValuePair<string, string>> ReadRateRequestHeaders(int expectedBytes) => new[] + { + new KeyValuePair<string, string>(HeaderNames.Method, "POST"), + new KeyValuePair<string, string>(HeaderNames.Path, "/" + expectedBytes), + new KeyValuePair<string, string>(HeaderNames.Scheme, "https"), + new KeyValuePair<string, string>(HeaderNames.Authority, "localhost:80"), + }; + + public static readonly byte[] _helloBytes = Encoding.ASCII.GetBytes("hello"); + public static readonly byte[] _worldBytes = Encoding.ASCII.GetBytes("world"); + public static readonly byte[] _helloWorldBytes = Encoding.ASCII.GetBytes("hello, world"); + public static readonly byte[] _noData = new byte[0]; + public static readonly byte[] _maxData = Encoding.ASCII.GetBytes(new string('a', Http2PeerSettings.MinAllowedMaxFrameSize)); + + internal readonly Http2PeerSettings _clientSettings = new Http2PeerSettings(); + internal readonly HPackEncoder _hpackEncoder = new HPackEncoder(); + internal readonly HPackDecoder _hpackDecoder; + private readonly byte[] _headerEncodingBuffer = new byte[Http2PeerSettings.MinAllowedMaxFrameSize]; + + public readonly Dictionary<string, string> _decodedHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); + + internal DuplexPipe.DuplexPipePair _pair; + public long _bytesReceived; + + public Http2Utilities(ConnectionContext clientConnectionContext, ILogger logger, CancellationToken stopToken) + { + _hpackDecoder = new HPackDecoder((int)_clientSettings.HeaderTableSize, MaxRequestHeaderFieldSize); + _pair = new DuplexPipe.DuplexPipePair(transport: null, application: clientConnectionContext.Transport); + Logger = logger; + StopToken = stopToken; + } + + public ILogger Logger { get; } + public CancellationToken StopToken { get; } + + void IHttpHeadersHandler.OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) + { + _decodedHeaders[GetAsciiStringNonNullCharacters(name)] = GetAsciiOrUTF8StringNonNullCharacters(value); + } + + public unsafe string GetAsciiStringNonNullCharacters(ReadOnlySpan<byte> span) + { + if (span.IsEmpty) + { + return string.Empty; + } + + var asciiString = new string('\0', span.Length); + + fixed (char* output = asciiString) + fixed (byte* buffer = span) + { + // This version if AsciiUtilities returns null if there are any null (0 byte) characters + // in the string + if (!StringUtilities.TryGetAsciiString(buffer, output, span.Length)) + { + throw new InvalidOperationException(); + } + } + return asciiString; + } + + public unsafe string GetAsciiOrUTF8StringNonNullCharacters(ReadOnlySpan<byte> span) + { + if (span.IsEmpty) + { + return string.Empty; + } + + var resultString = new string('\0', span.Length); + + fixed (char* output = resultString) + fixed (byte* buffer = span) + { + // This version if AsciiUtilities returns null if there are any null (0 byte) characters + // in the string + if (!StringUtilities.TryGetAsciiString(buffer, output, span.Length)) + { + // null characters are considered invalid + if (span.IndexOf((byte)0) != -1) + { + throw new InvalidOperationException(); + } + + try + { + resultString = HeaderValueEncoding.GetString(buffer, span.Length); + } + catch (DecoderFallbackException) + { + throw new InvalidOperationException(); + } + } + } + return resultString; + } + + void IHttpHeadersHandler.OnHeadersComplete(bool endStream) { } + + public async Task InitializeConnectionAsync(int expectedSettingsCount = 3) + { + await SendPreambleAsync().ConfigureAwait(false); + await SendSettingsAsync(); + + await ExpectAsync(Http2FrameType.SETTINGS, + withLength: expectedSettingsCount * Http2FrameReader.SettingSize, + withFlags: 0, + withStreamId: 0); + + await ExpectAsync(Http2FrameType.WINDOW_UPDATE, + withLength: 4, + withFlags: 0, + withStreamId: 0); + + await ExpectAsync(Http2FrameType.SETTINGS, + withLength: 0, + withFlags: (byte)Http2SettingsFrameFlags.ACK, + withStreamId: 0); + } + + public Task StartStreamAsync(int streamId, IEnumerable<KeyValuePair<string, string>> headers, bool endStream) + { + var writableBuffer = _pair.Application.Output; + var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); + + var frame = new Http2Frame(); + frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId); + + var buffer = _headerEncodingBuffer.AsSpan(); + var done = _hpackEncoder.BeginEncode(headers, buffer, out var length); + frame.PayloadLength = length; + + if (done) + { + frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS; + } + + if (endStream) + { + frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM; + } + + WriteHeader(frame, writableBuffer); + writableBuffer.Write(buffer.Slice(0, length)); + + while (!done) + { + frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId); + + done = _hpackEncoder.Encode(buffer, out length); + frame.PayloadLength = length; + + if (done) + { + frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS; + } + + WriteHeader(frame, writableBuffer); + writableBuffer.Write(buffer.Slice(0, length)); + } + + return FlushAsync(writableBuffer); + } + + internal Dictionary<string, string> DecodeHeaders(Http2FrameWithPayload frame, bool endHeaders = false) + { + Assert.Equal(Http2FrameType.HEADERS, frame.Type); + _hpackDecoder.Decode(frame.PayloadSequence, endHeaders, handler: this); + return _decodedHeaders; + } + + internal void ResetHeaders() + { + _decodedHeaders.Clear(); + } + + /* https://tools.ietf.org/html/rfc7540#section-4.1 + +-----------------------------------------------+ + | Length (24) | + +---------------+---------------+---------------+ + | Type (8) | Flags (8) | + +-+-------------+---------------+-------------------------------+ + |R| Stream Identifier (31) | + +=+=============================================================+ + | Frame Payload (0...) ... + +---------------------------------------------------------------+ + */ + internal static void WriteHeader(Http2Frame frame, PipeWriter output) + { + var buffer = output.GetSpan(Http2FrameReader.HeaderLength); + + Bitshifter.WriteUInt24BigEndian(buffer, (uint)frame.PayloadLength); + buffer = buffer.Slice(3); + + buffer[0] = (byte)frame.Type; + buffer[1] = frame.Flags; + buffer = buffer.Slice(2); + + Bitshifter.WriteUInt31BigEndian(buffer, (uint)frame.StreamId, preserveHighestBit: false); + + output.Advance(Http2FrameReader.HeaderLength); + } + + /* https://tools.ietf.org/html/rfc7540#section-6.2 + +---------------+ + |Pad Length? (8)| + +-+-------------+-----------------------------------------------+ + | Header Block Fragment (*) ... + +---------------------------------------------------------------+ + | Padding (*) ... + +---------------------------------------------------------------+ + */ + public Task SendHeadersWithPaddingAsync(int streamId, IEnumerable<KeyValuePair<string, string>> headers, byte padLength, bool endStream) + { + var writableBuffer = _pair.Application.Output; + var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); + + var frame = new Http2Frame(); + + frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PADDED, streamId); + frame.HeadersPadLength = padLength; + + var extendedHeaderLength = 1; // Padding length field + var buffer = _headerEncodingBuffer.AsSpan(); + var extendedHeader = buffer.Slice(0, extendedHeaderLength); + extendedHeader[0] = padLength; + var payload = buffer.Slice(extendedHeaderLength, buffer.Length - padLength - extendedHeaderLength); + + _hpackEncoder.BeginEncode(headers, payload, out var length); + var padding = buffer.Slice(extendedHeaderLength + length, padLength); + padding.Fill(0); + + frame.PayloadLength = extendedHeaderLength + length + padLength; + + if (endStream) + { + frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM; + } + + WriteHeader(frame, writableBuffer); + writableBuffer.Write(buffer.Slice(0, frame.PayloadLength)); + return FlushAsync(writableBuffer); + } + + /* https://tools.ietf.org/html/rfc7540#section-6.2 + +-+-------------+-----------------------------------------------+ + |E| Stream Dependency? (31) | + +-+-------------+-----------------------------------------------+ + | Weight? (8) | + +-+-------------+-----------------------------------------------+ + | Header Block Fragment (*) ... + +---------------------------------------------------------------+ + */ + public Task SendHeadersWithPriorityAsync(int streamId, IEnumerable<KeyValuePair<string, string>> headers, byte priority, int streamDependency, bool endStream) + { + var writableBuffer = _pair.Application.Output; + var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); + + var frame = new Http2Frame(); + frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PRIORITY, streamId); + frame.HeadersPriorityWeight = priority; + frame.HeadersStreamDependency = streamDependency; + + var extendedHeaderLength = 5; // stream dependency + weight + var buffer = _headerEncodingBuffer.AsSpan(); + var extendedHeader = buffer.Slice(0, extendedHeaderLength); + Bitshifter.WriteUInt31BigEndian(extendedHeader, (uint)streamDependency); + extendedHeader[4] = priority; + var payload = buffer.Slice(extendedHeaderLength); + + _hpackEncoder.BeginEncode(headers, payload, out var length); + + frame.PayloadLength = extendedHeaderLength + length; + + if (endStream) + { + frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM; + } + + WriteHeader(frame, writableBuffer); + writableBuffer.Write(buffer.Slice(0, frame.PayloadLength)); + return FlushAsync(writableBuffer); + } + + /* https://tools.ietf.org/html/rfc7540#section-6.2 + +---------------+ + |Pad Length? (8)| + +-+-------------+-----------------------------------------------+ + |E| Stream Dependency? (31) | + +-+-------------+-----------------------------------------------+ + | Weight? (8) | + +-+-------------+-----------------------------------------------+ + | Header Block Fragment (*) ... + +---------------------------------------------------------------+ + | Padding (*) ... + +---------------------------------------------------------------+ + */ + public Task SendHeadersWithPaddingAndPriorityAsync(int streamId, IEnumerable<KeyValuePair<string, string>> headers, byte padLength, byte priority, int streamDependency, bool endStream) + { + var writableBuffer = _pair.Application.Output; + var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously); + + var frame = new Http2Frame(); + frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PADDED | Http2HeadersFrameFlags.PRIORITY, streamId); + frame.HeadersPadLength = padLength; + frame.HeadersPriorityWeight = priority; + frame.HeadersStreamDependency = streamDependency; + + var extendedHeaderLength = 6; // pad length + stream dependency + weight + var buffer = _headerEncodingBuffer.AsSpan(); + var extendedHeader = buffer.Slice(0, extendedHeaderLength); + extendedHeader[0] = padLength; + Bitshifter.WriteUInt31BigEndian(extendedHeader.Slice(1), (uint)streamDependency); + extendedHeader[5] = priority; + var payload = buffer.Slice(extendedHeaderLength, buffer.Length - padLength - extendedHeaderLength); + + _hpackEncoder.BeginEncode(headers, payload, out var length); + var padding = buffer.Slice(extendedHeaderLength + length, padLength); + padding.Fill(0); + + frame.PayloadLength = extendedHeaderLength + length + padLength; + + if (endStream) + { + frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM; + } + + WriteHeader(frame, writableBuffer); + writableBuffer.Write(buffer.Slice(0, frame.PayloadLength)); + return FlushAsync(writableBuffer); + } + + public Task SendAsync(ReadOnlySpan<byte> span) + { + var writableBuffer = _pair.Application.Output; + writableBuffer.Write(span); + return FlushAsync(writableBuffer); + } + + public static async Task FlushAsync(PipeWriter writableBuffer) + { + await writableBuffer.FlushAsync().AsTask().DefaultTimeout(); + } + + public Task SendPreambleAsync() => SendAsync(ClientPreface); + + public async Task SendSettingsAsync() + { + var writableBuffer = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareSettings(Http2SettingsFrameFlags.NONE); + var settings = _clientSettings.GetNonProtocolDefaults(); + var payload = new byte[settings.Count * Http2FrameReader.SettingSize]; + frame.PayloadLength = payload.Length; + WriteSettings(settings, payload); + WriteHeader(frame, writableBuffer); + await SendAsync(payload); + } + + internal static void WriteSettings(IList<Http2PeerSetting> settings, Span<byte> destination) + { + foreach (var setting in settings) + { + BinaryPrimitives.WriteUInt16BigEndian(destination, (ushort)setting.Parameter); + BinaryPrimitives.WriteUInt32BigEndian(destination.Slice(2), setting.Value); + destination = destination.Slice(Http2FrameReader.SettingSize); + } + } + + public async Task SendSettingsAckWithInvalidLengthAsync(int length) + { + var writableBuffer = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareSettings(Http2SettingsFrameFlags.ACK); + frame.PayloadLength = length; + WriteHeader(frame, writableBuffer); + await SendAsync(new byte[length]); + } + + public async Task SendSettingsWithInvalidStreamIdAsync(int streamId) + { + var writableBuffer = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareSettings(Http2SettingsFrameFlags.NONE); + frame.StreamId = streamId; + var settings = _clientSettings.GetNonProtocolDefaults(); + var payload = new byte[settings.Count * Http2FrameReader.SettingSize]; + frame.PayloadLength = payload.Length; + WriteSettings(settings, payload); + WriteHeader(frame, writableBuffer); + await SendAsync(payload); + } + + public async Task SendSettingsWithInvalidLengthAsync(int length) + { + var writableBuffer = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareSettings(Http2SettingsFrameFlags.NONE); + + frame.PayloadLength = length; + var payload = new byte[length]; + WriteHeader(frame, writableBuffer); + await SendAsync(payload); + } + + internal async Task SendSettingsWithInvalidParameterValueAsync(Http2SettingsParameter parameter, uint value) + { + var writableBuffer = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareSettings(Http2SettingsFrameFlags.NONE); + frame.PayloadLength = 6; + var payload = new byte[Http2FrameReader.SettingSize]; + payload[0] = (byte)((ushort)parameter >> 8); + payload[1] = (byte)(ushort)parameter; + payload[2] = (byte)(value >> 24); + payload[3] = (byte)(value >> 16); + payload[4] = (byte)(value >> 8); + payload[5] = (byte)value; + + WriteHeader(frame, writableBuffer); + await SendAsync(payload); + } + + public Task SendPushPromiseFrameAsync() + { + var writableBuffer = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PayloadLength = 0; + frame.Type = Http2FrameType.PUSH_PROMISE; + frame.StreamId = 1; + + WriteHeader(frame, writableBuffer); + return FlushAsync(writableBuffer); + } + + internal async Task<bool> SendHeadersAsync(int streamId, Http2HeadersFrameFlags flags, IEnumerable<KeyValuePair<string, string>> headers) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareHeaders(flags, streamId); + var buffer = _headerEncodingBuffer.AsMemory(); + var done = _hpackEncoder.BeginEncode(headers, buffer.Span, out var length); + frame.PayloadLength = length; + + WriteHeader(frame, outputWriter); + await SendAsync(buffer.Span.Slice(0, length)); + + return done; + } + + internal async Task SendHeadersAsync(int streamId, Http2HeadersFrameFlags flags, byte[] headerBlock) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareHeaders(flags, streamId); + frame.PayloadLength = headerBlock.Length; + + WriteHeader(frame, outputWriter); + await SendAsync(headerBlock); + } + + public async Task SendInvalidHeadersFrameAsync(int streamId, int payloadLength, byte padLength) + { + Assert.True(padLength >= payloadLength, $"{nameof(padLength)} must be greater than or equal to {nameof(payloadLength)} to create an invalid frame."); + + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareHeaders(Http2HeadersFrameFlags.PADDED, streamId); + frame.PayloadLength = payloadLength; + var payload = new byte[payloadLength]; + if (payloadLength > 0) + { + payload[0] = padLength; + } + + WriteHeader(frame, outputWriter); + await SendAsync(payload); + } + + public async Task SendIncompleteHeadersFrameAsync(int streamId) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId); + frame.PayloadLength = 3; + var payload = new byte[3]; + // Set up an incomplete Literal Header Field w/ Incremental Indexing frame, + // with an incomplete new name + payload[0] = 0; + payload[1] = 2; + payload[2] = (byte)'a'; + + WriteHeader(frame, outputWriter); + await SendAsync(payload); + } + + internal async Task<bool> SendContinuationAsync(int streamId, Http2ContinuationFrameFlags flags) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareContinuation(flags, streamId); + var buffer = _headerEncodingBuffer.AsMemory(); + var done = _hpackEncoder.Encode(buffer.Span, out var length); + frame.PayloadLength = length; + + WriteHeader(frame, outputWriter); + await SendAsync(buffer.Span.Slice(0, length)); + + return done; + } + + internal async Task SendContinuationAsync(int streamId, Http2ContinuationFrameFlags flags, byte[] payload) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareContinuation(flags, streamId); + frame.PayloadLength = payload.Length; + + WriteHeader(frame, outputWriter); + await SendAsync(payload); + } + + internal async Task<bool> SendContinuationAsync(int streamId, Http2ContinuationFrameFlags flags, IEnumerable<KeyValuePair<string, string>> headers) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareContinuation(flags, streamId); + var buffer = _headerEncodingBuffer.AsMemory(); + var done = _hpackEncoder.BeginEncode(headers, buffer.Span, out var length); + frame.PayloadLength = length; + + WriteHeader(frame, outputWriter); + await SendAsync(buffer.Span.Slice(0, length)); + + return done; + } + + internal Task SendEmptyContinuationFrameAsync(int streamId, Http2ContinuationFrameFlags flags) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareContinuation(flags, streamId); + frame.PayloadLength = 0; + + WriteHeader(frame, outputWriter); + return FlushAsync(outputWriter); + } + + public async Task SendIncompleteContinuationFrameAsync(int streamId) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareContinuation(Http2ContinuationFrameFlags.END_HEADERS, streamId); + frame.PayloadLength = 3; + var payload = new byte[3]; + // Set up an incomplete Literal Header Field w/ Incremental Indexing frame, + // with an incomplete new name + payload[0] = 0; + payload[1] = 2; + payload[2] = (byte)'a'; + + WriteHeader(frame, outputWriter); + await SendAsync(payload); + } + + public Task SendDataAsync(int streamId, Memory<byte> data, bool endStream) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareData(streamId); + frame.PayloadLength = data.Length; + frame.DataFlags = endStream ? Http2DataFrameFlags.END_STREAM : Http2DataFrameFlags.NONE; + + WriteHeader(frame, outputWriter); + return SendAsync(data.Span); + } + + public async Task SendDataWithPaddingAsync(int streamId, Memory<byte> data, byte padLength, bool endStream) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareData(streamId, padLength); + frame.PayloadLength = data.Length + 1 + padLength; + + if (endStream) + { + frame.DataFlags |= Http2DataFrameFlags.END_STREAM; + } + + WriteHeader(frame, outputWriter); + outputWriter.GetSpan(1)[0] = padLength; + outputWriter.Advance(1); + await SendAsync(data.Span); + await SendAsync(new byte[padLength]); + } + + public Task SendInvalidDataFrameAsync(int streamId, int frameLength, byte padLength) + { + Assert.True(padLength >= frameLength, $"{nameof(padLength)} must be greater than or equal to {nameof(frameLength)} to create an invalid frame."); + + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + + frame.PrepareData(streamId); + frame.DataFlags = Http2DataFrameFlags.PADDED; + frame.PayloadLength = frameLength; + var payload = new byte[frameLength]; + if (frameLength > 0) + { + payload[0] = padLength; + } + + WriteHeader(frame, outputWriter); + return SendAsync(payload); + } + + internal Task SendPingAsync(Http2PingFrameFlags flags) + { + var outputWriter = _pair.Application.Output; + var pingFrame = new Http2Frame(); + pingFrame.PreparePing(flags); + WriteHeader(pingFrame, outputWriter); + return SendAsync(new byte[8]); // Empty payload + } + + public Task SendPingWithInvalidLengthAsync(int length) + { + var outputWriter = _pair.Application.Output; + var pingFrame = new Http2Frame(); + pingFrame.PreparePing(Http2PingFrameFlags.NONE); + pingFrame.PayloadLength = length; + WriteHeader(pingFrame, outputWriter); + return SendAsync(new byte[length]); + } + + public Task SendPingWithInvalidStreamIdAsync(int streamId) + { + Assert.NotEqual(0, streamId); + + var outputWriter = _pair.Application.Output; + var pingFrame = new Http2Frame(); + pingFrame.PreparePing(Http2PingFrameFlags.NONE); + pingFrame.StreamId = streamId; + WriteHeader(pingFrame, outputWriter); + return SendAsync(new byte[pingFrame.PayloadLength]); + } + + /* https://tools.ietf.org/html/rfc7540#section-6.3 + +-+-------------------------------------------------------------+ + |E| Stream Dependency (31) | + +-+-------------+-----------------------------------------------+ + | Weight (8) | + +-+-------------+ + */ + public Task SendPriorityAsync(int streamId, int streamDependency = 0) + { + var outputWriter = _pair.Application.Output; + var priorityFrame = new Http2Frame(); + priorityFrame.PreparePriority(streamId, streamDependency: streamDependency, exclusive: false, weight: 0); + + var payload = new byte[priorityFrame.PayloadLength].AsSpan(); + Bitshifter.WriteUInt31BigEndian(payload, (uint)streamDependency); + payload[4] = 0; // Weight + + WriteHeader(priorityFrame, outputWriter); + return SendAsync(payload); + } + + public Task SendInvalidPriorityFrameAsync(int streamId, int length) + { + var outputWriter = _pair.Application.Output; + var priorityFrame = new Http2Frame(); + priorityFrame.PreparePriority(streamId, streamDependency: 0, exclusive: false, weight: 0); + priorityFrame.PayloadLength = length; + + WriteHeader(priorityFrame, outputWriter); + return SendAsync(new byte[length]); + } + + /* https://tools.ietf.org/html/rfc7540#section-6.4 + +---------------------------------------------------------------+ + | Error Code (32) | + +---------------------------------------------------------------+ + */ + public Task SendRstStreamAsync(int streamId) + { + var outputWriter = _pair.Application.Output; + var rstStreamFrame = new Http2Frame(); + rstStreamFrame.PrepareRstStream(streamId, Http2ErrorCode.CANCEL); + var payload = new byte[rstStreamFrame.PayloadLength]; + BinaryPrimitives.WriteUInt32BigEndian(payload, (uint)Http2ErrorCode.CANCEL); + + WriteHeader(rstStreamFrame, outputWriter); + return SendAsync(payload); + } + + public Task SendInvalidRstStreamFrameAsync(int streamId, int length) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareRstStream(streamId, Http2ErrorCode.CANCEL); + frame.PayloadLength = length; + WriteHeader(frame, outputWriter); + return SendAsync(new byte[length]); + } + + public Task SendGoAwayAsync() + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareGoAway(0, Http2ErrorCode.NO_ERROR); + WriteHeader(frame, outputWriter); + return SendAsync(new byte[frame.PayloadLength]); + } + + public Task SendInvalidGoAwayFrameAsync() + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareGoAway(0, Http2ErrorCode.NO_ERROR); + frame.StreamId = 1; + WriteHeader(frame, outputWriter); + return SendAsync(new byte[frame.PayloadLength]); + } + + public Task SendWindowUpdateAsync(int streamId, int sizeIncrement) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareWindowUpdate(streamId, sizeIncrement); + WriteHeader(frame, outputWriter); + var buffer = outputWriter.GetSpan(4); + BinaryPrimitives.WriteUInt32BigEndian(buffer, (uint)sizeIncrement); + outputWriter.Advance(4); + return FlushAsync(outputWriter); + } + + public Task SendInvalidWindowUpdateAsync(int streamId, int sizeIncrement, int length) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + frame.PrepareWindowUpdate(streamId, sizeIncrement); + frame.PayloadLength = length; + WriteHeader(frame, outputWriter); + return SendAsync(new byte[length]); + } + + public Task SendUnknownFrameTypeAsync(int streamId, int frameType) + { + var outputWriter = _pair.Application.Output; + var frame = new Http2Frame(); + frame.StreamId = streamId; + frame.Type = (Http2FrameType)frameType; + frame.PayloadLength = 0; + WriteHeader(frame, outputWriter); + return FlushAsync(outputWriter); + } + + internal async Task<Http2FrameWithPayload> ReceiveFrameAsync(uint maxFrameSize = Http2PeerSettings.DefaultMaxFrameSize) + { + var frame = new Http2FrameWithPayload(); + + while (true) + { + var result = await _pair.Application.Input.ReadAsync().AsTask().DefaultTimeout(); + var buffer = result.Buffer; + var consumed = buffer.Start; + var examined = buffer.Start; + + try + { + Assert.True(buffer.Length > 0); + + if (Http2FrameReader.TryReadFrame(ref buffer, frame, maxFrameSize, out var framePayload)) + { + consumed = examined = framePayload.End; + frame.Payload = framePayload.ToArray(); + return frame; + } + else + { + examined = buffer.End; + } + + if (result.IsCompleted) + { + throw new IOException("The reader completed without returning a frame."); + } + } + finally + { + _bytesReceived += buffer.Slice(buffer.Start, consumed).Length; + _pair.Application.Input.AdvanceTo(consumed, examined); + } + } + } + + internal async Task<Http2FrameWithPayload> ExpectAsync(Http2FrameType type, int withLength, byte withFlags, int withStreamId) + { + var frame = await ReceiveFrameAsync((uint)withLength); + + Assert.Equal(type, frame.Type); + Assert.Equal(withLength, frame.PayloadLength); + Assert.Equal(withFlags, frame.Flags); + Assert.Equal(withStreamId, frame.StreamId); + + return frame; + } + + public async Task StopConnectionAsync(int expectedLastStreamId, bool ignoreNonGoAwayFrames) + { + await SendGoAwayAsync(); + await WaitForConnectionStopAsync(expectedLastStreamId, ignoreNonGoAwayFrames); + + _pair.Application.Output.Complete(); + } + + public Task WaitForConnectionStopAsync(int expectedLastStreamId, bool ignoreNonGoAwayFrames) + { + return WaitForConnectionErrorAsync<Exception>(ignoreNonGoAwayFrames, expectedLastStreamId, Http2ErrorCode.NO_ERROR); + } + + internal Task ReceiveHeadersAsync(int expectedStreamId, Action<IDictionary<string, string>> verifyHeaders = null) + => ReceiveHeadersAsync(expectedStreamId, endStream: false, verifyHeaders); + + internal async Task ReceiveHeadersAsync(int expectedStreamId, bool endStream = false, Action<IDictionary<string, string>> verifyHeaders = null) + { + var headersFrame = await ReceiveFrameAsync(); + Assert.Equal(Http2FrameType.HEADERS, headersFrame.Type); + Assert.Equal(expectedStreamId, headersFrame.StreamId); + Assert.True((headersFrame.Flags & (byte)Http2HeadersFrameFlags.END_HEADERS) != 0); + Assert.Equal(endStream, (headersFrame.Flags & (byte)Http2HeadersFrameFlags.END_STREAM) != 0); + Logger.LogInformation("Received headers in a single frame."); + + ResetHeaders(); + DecodeHeaders(headersFrame); + verifyHeaders?.Invoke(_decodedHeaders); + } + + internal static void VerifyDataFrame(Http2Frame frame, int expectedStreamId, bool endOfStream, int length) + { + Assert.Equal(Http2FrameType.DATA, frame.Type); + Assert.Equal(expectedStreamId, frame.StreamId); + Assert.Equal(endOfStream ? Http2DataFrameFlags.END_STREAM : Http2DataFrameFlags.NONE, frame.DataFlags); + Assert.Equal(length, frame.PayloadLength); + } + + internal void VerifyGoAway(Http2Frame frame, int expectedLastStreamId, Http2ErrorCode expectedErrorCode) + { + Assert.Equal(Http2FrameType.GOAWAY, frame.Type); + Assert.Equal(8, frame.PayloadLength); + Assert.Equal(0, frame.Flags); + Assert.Equal(0, frame.StreamId); + Assert.Equal(expectedLastStreamId, frame.GoAwayLastStreamId); + Assert.Equal(expectedErrorCode, frame.GoAwayErrorCode); + } + + internal static void VerifyResetFrame(Http2Frame frame, int expectedStreamId, Http2ErrorCode expectedErrorCode) + { + Assert.Equal(Http2FrameType.RST_STREAM, frame.Type); + Assert.Equal(expectedStreamId, frame.StreamId); + Assert.Equal(expectedErrorCode, frame.RstStreamErrorCode); + Assert.Equal(4, frame.PayloadLength); + Assert.Equal(0, frame.Flags); + } + + internal async Task WaitForConnectionErrorAsync<TException>(bool ignoreNonGoAwayFrames, int expectedLastStreamId, Http2ErrorCode expectedErrorCode) + where TException : Exception + { + await WaitForConnectionErrorAsyncDoNotCloseTransport<TException>(ignoreNonGoAwayFrames, expectedLastStreamId, expectedErrorCode); + _pair.Application.Output.Complete(); + } + + internal async Task WaitForConnectionErrorAsyncDoNotCloseTransport<TException>(bool ignoreNonGoAwayFrames, int expectedLastStreamId, Http2ErrorCode expectedErrorCode) + where TException : Exception + { + var frame = await ReceiveFrameAsync(); + + if (ignoreNonGoAwayFrames) + { + while (frame.Type != Http2FrameType.GOAWAY) + { + frame = await ReceiveFrameAsync(); + } + } + + VerifyGoAway(frame, expectedLastStreamId, expectedErrorCode); + } + + internal async Task WaitForStreamErrorAsync(int expectedStreamId, Http2ErrorCode expectedErrorCode) + { + var frame = await ReceiveFrameAsync(); + + Assert.Equal(Http2FrameType.RST_STREAM, frame.Type); + Assert.Equal(4, frame.PayloadLength); + Assert.Equal(0, frame.Flags); + Assert.Equal(expectedStreamId, frame.StreamId); + Assert.Equal(expectedErrorCode, frame.RstStreamErrorCode); + } + + internal class Http2FrameWithPayload : Http2Frame + { + public Http2FrameWithPayload() : base() + { + } + + // This does not contain extended headers + public Memory<byte> Payload { get; set; } + + public ReadOnlySequence<byte> PayloadSequence => new ReadOnlySequence<byte>(Payload); + } + + private static class Assert + { + public static void True(bool condition, string message = "") + { + if (!condition) + { + throw new Exception($"Assert.True failed: '{message}'"); + } + } + + public static void Equal<T>(T expected, T actual) + { + if (!expected.Equals(actual)) + { + throw new Exception($"Assert.Equal('{expected}', '{actual}') failed"); + } + } + + public static void Equal(string expected, string actual, bool ignoreCase = false) + { + if (!expected.Equals(actual, ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture)) + { + throw new Exception($"Assert.Equal('{expected}', '{actual}') failed"); + } + } + + public static void NotEqual<T>(T value1, T value2) + { + if (value1.Equals(value2)) + { + throw new Exception($"Assert.NotEqual('{value1}', '{value2}') failed"); + } + } + + public static void Contains<T>(IEnumerable<T> collection, T value) + { + if (!collection.Contains(value)) + { + throw new Exception($"Assert.Contains(collection, '{value}') failed"); + } + } + } + } +} diff --git a/src/Shared/Http2cat/TaskTimeoutExtensions.cs b/src/Shared/Http2cat/TaskTimeoutExtensions.cs new file mode 100644 index 0000000000..a293c1c66b --- /dev/null +++ b/src/Shared/Http2cat/TaskTimeoutExtensions.cs @@ -0,0 +1,85 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Threading.Tasks +{ + internal static class TaskTimeoutExtensions + { + public static TimeSpan DefaultTimeoutTimeSpan { get; } = TimeSpan.FromSeconds(5); + + public static Task<T> DefaultTimeout<T>(this ValueTask<T> task) + { + return task.AsTask().TimeoutAfter(DefaultTimeoutTimeSpan); + } + + public static Task DefaultTimeout(this ValueTask task) + { + return task.AsTask().TimeoutAfter(DefaultTimeoutTimeSpan); + } + + public static Task<T> DefaultTimeout<T>(this Task<T> task) + { + return task.TimeoutAfter(DefaultTimeoutTimeSpan); + } + + public static Task DefaultTimeout(this Task task) + { + return task.TimeoutAfter(DefaultTimeoutTimeSpan); + } + + private static async Task<T> TimeoutAfter<T>(this Task<T> task, TimeSpan timeout, + [CallerFilePath] string filePath = null, + [CallerLineNumber] int lineNumber = default) + { + // Don't create a timer if the task is already completed + // or the debugger is attached + if (task.IsCompleted || Debugger.IsAttached) + { + return await task; + } + + var cts = new CancellationTokenSource(); + if (task == await Task.WhenAny(task, Task.Delay(timeout, cts.Token))) + { + cts.Cancel(); + return await task; + } + else + { + throw new TimeoutException(CreateMessage(timeout, filePath, lineNumber)); + } + } + + private static async Task TimeoutAfter(this Task task, TimeSpan timeout, + [CallerFilePath] string filePath = null, + [CallerLineNumber] int lineNumber = default) + { + // Don't create a timer if the task is already completed + // or the debugger is attached + if (task.IsCompleted || Debugger.IsAttached) + { + await task; + return; + } + + var cts = new CancellationTokenSource(); + if (task == await Task.WhenAny(task, Task.Delay(timeout, cts.Token))) + { + cts.Cancel(); + await task; + } + else + { + throw new TimeoutException(CreateMessage(timeout, filePath, lineNumber)); + } + } + + private static string CreateMessage(TimeSpan timeout, string filePath, int lineNumber) + => string.IsNullOrEmpty(filePath) + ? $"The operation timed out after reaching the limit of {timeout.TotalMilliseconds}ms." + : $"The operation at {filePath}:{lineNumber} timed out after reaching the limit of {timeout.TotalMilliseconds}ms."; + } +} diff --git a/src/Shared/HttpSys/Constants.cs b/src/Shared/HttpSys/Constants.cs index 6f861c239f..4d0576c477 100644 --- a/src/Shared/HttpSys/Constants.cs +++ b/src/Shared/HttpSys/Constants.cs @@ -15,8 +15,8 @@ namespace Microsoft.AspNetCore.HttpSys.Internal internal const string SchemeDelimiter = "://"; internal const string DefaultServerAddress = "http://localhost:5000"; - internal static Version V1_0 = new Version(1, 0); - internal static Version V1_1 = new Version(1, 1); - internal static Version V2 = new Version(2, 0); + internal static readonly Version V1_0 = new Version(1, 0); + internal static readonly Version V1_1 = new Version(1, 1); + internal static readonly Version V2 = new Version(2, 0); } } diff --git a/src/Shared/HttpSys/Extensions.cs b/src/Shared/HttpSys/Extensions.cs new file mode 100644 index 0000000000..c813991357 --- /dev/null +++ b/src/Shared/HttpSys/Extensions.cs @@ -0,0 +1,18 @@ +// 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; + +namespace Microsoft.AspNetCore.HttpSys.Internal +{ + internal static class Extensions + { + public static string GetHttpProtocolVersion(this Version version) => version switch + { + { Major: 2, Minor: 0 } => "HTTP/2", + { Major: 1, Minor: 1 } => "HTTP/1.1", + { Major: 1, Minor: 0 } => "HTTP/1.0", + _ => "HTTP/" + version.ToString(2) + }; + } +} diff --git a/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs b/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs index aa5d884061..2e69d7bc40 100644 --- a/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs +++ b/src/Shared/HttpSys/NativeInterop/HttpApiTypes.cs @@ -51,6 +51,16 @@ namespace Microsoft.AspNetCore.HttpSys.Internal HttpResponseInfoTypeQosProperty, } + internal enum HTTP_REQUEST_PROPERTY + { + HttpRequestPropertyIsb, + HttpRequestPropertyTcpInfoV0, + HttpRequestPropertyQuicStats, + HttpRequestPropertyTcpInfoV1, + HttpRequestPropertySni, + HttpRequestPropertyStreamError, + } + internal enum HTTP_TIMEOUT_TYPE { EntityBody, @@ -61,6 +71,11 @@ namespace Microsoft.AspNetCore.HttpSys.Internal MinSendRate, } + internal struct HTTP_REQUEST_PROPERTY_STREAM_ERROR + { + internal uint ErrorCode; + } + internal const int MaxTimeout = 6; [StructLayout(LayoutKind.Sequential)] @@ -88,6 +103,9 @@ namespace Microsoft.AspNetCore.HttpSys.Internal [FieldOffset(8)] internal FromFileHandle fromFile; + + [FieldOffset(8)] + internal Trailers trailers; } [StructLayout(LayoutKind.Sequential)] @@ -106,6 +124,13 @@ namespace Microsoft.AspNetCore.HttpSys.Internal internal IntPtr fileHandle; } + [StructLayout(LayoutKind.Sequential)] + internal struct Trailers + { + internal ushort trailerCount; + internal IntPtr pTrailers; + } + [StructLayout(LayoutKind.Sequential)] internal struct HTTPAPI_VERSION { @@ -362,10 +387,12 @@ namespace Microsoft.AspNetCore.HttpSys.Internal internal enum HTTP_DATA_CHUNK_TYPE : int { - HttpDataChunkFromMemory = 0, - HttpDataChunkFromFileHandle = 1, - HttpDataChunkFromFragmentCache = 2, - HttpDataChunkMaximum = 3, + HttpDataChunkFromMemory, + HttpDataChunkFromFileHandle, + HttpDataChunkFromFragmentCache, + HttpDataChunkFromFragmentCacheEx, + HttpDataChunkTrailers, + HttpDataChunkMaximum, } [StructLayout(LayoutKind.Sequential)] diff --git a/src/Shared/HttpSys/RequestProcessing/HeaderCollection.cs b/src/Shared/HttpSys/RequestProcessing/HeaderCollection.cs index 504c434667..d1ed182f91 100644 --- a/src/Shared/HttpSys/RequestProcessing/HeaderCollection.cs +++ b/src/Shared/HttpSys/RequestProcessing/HeaderCollection.cs @@ -12,12 +12,42 @@ namespace Microsoft.AspNetCore.HttpSys.Internal { internal class HeaderCollection : IHeaderDictionary { + // https://tools.ietf.org/html/rfc7230#section-4.1.2 + internal static readonly HashSet<string> DisallowedTrailers = new HashSet<string>(StringComparer.OrdinalIgnoreCase) + { + // Message framing headers. + HeaderNames.TransferEncoding, HeaderNames.ContentLength, + + // Routing headers. + HeaderNames.Host, + + // Request modifiers: controls and conditionals. + // rfc7231#section-5.1: Controls. + HeaderNames.CacheControl, HeaderNames.Expect, HeaderNames.MaxForwards, HeaderNames.Pragma, HeaderNames.Range, HeaderNames.TE, + + // rfc7231#section-5.2: Conditionals. + HeaderNames.IfMatch, HeaderNames.IfNoneMatch, HeaderNames.IfModifiedSince, HeaderNames.IfUnmodifiedSince, HeaderNames.IfRange, + + // Authentication headers. + HeaderNames.WWWAuthenticate, HeaderNames.Authorization, HeaderNames.ProxyAuthenticate, HeaderNames.ProxyAuthorization, HeaderNames.SetCookie, HeaderNames.Cookie, + + // Response control data. + // rfc7231#section-7.1: Control Data. + HeaderNames.Age, HeaderNames.Expires, HeaderNames.Date, HeaderNames.Location, HeaderNames.RetryAfter, HeaderNames.Vary, HeaderNames.Warning, + + // Content-Encoding, Content-Type, Content-Range, and Trailer itself. + HeaderNames.ContentEncoding, HeaderNames.ContentType, HeaderNames.ContentRange, HeaderNames.Trailer + }; + + // Should this instance check for prohibited trailers? + private readonly bool _checkTrailers; private long? _contentLength; private StringValues _contentLengthText; - public HeaderCollection() + public HeaderCollection(bool checkTrailers = false) : this(new Dictionary<string, StringValues>(4, StringComparer.OrdinalIgnoreCase)) { + _checkTrailers = checkTrailers; } public HeaderCollection(IDictionary<string, StringValues> store) @@ -39,6 +69,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } set { + ValidateRestrictedTrailers(key); ThrowIfReadOnly(); if (StringValues.IsNullOrEmpty(value)) { @@ -58,6 +89,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal get { return Store[key]; } set { + ValidateRestrictedTrailers(key); ThrowIfReadOnly(); ValidateHeaderCharacters(key); ValidateHeaderCharacters(value); @@ -105,6 +137,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } set { + ValidateRestrictedTrailers(HeaderNames.ContentLength); ThrowIfReadOnly(); if (value.HasValue) @@ -128,6 +161,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal public void Add(KeyValuePair<string, StringValues> item) { + ValidateRestrictedTrailers(item.Key); ThrowIfReadOnly(); ValidateHeaderCharacters(item.Key); ValidateHeaderCharacters(item.Value); @@ -136,6 +170,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal public void Add(string key, StringValues value) { + ValidateRestrictedTrailers(key); ThrowIfReadOnly(); ValidateHeaderCharacters(key); ValidateHeaderCharacters(value); @@ -144,6 +179,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal public void Append(string key, string value) { + ValidateRestrictedTrailers(key); ThrowIfReadOnly(); ValidateHeaderCharacters(key); ValidateHeaderCharacters(value); @@ -214,6 +250,11 @@ namespace Microsoft.AspNetCore.HttpSys.Internal { if (IsReadOnly) { + if (_checkTrailers) + { + throw new InvalidOperationException("The response trailers cannot be modified because the response has already completed. " + + "If this is a Content-Length response then you need to call HttpResponse.DeclareTrailer before starting the body."); + } throw new InvalidOperationException("The response headers cannot be modified because the response has already started."); } } @@ -239,5 +280,13 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } } } + + private void ValidateRestrictedTrailers(string key) + { + if (_checkTrailers && DisallowedTrailers.Contains(key)) + { + throw new InvalidOperationException($"The '{key}' header is not allowed in HTTP trailers."); + } + } } -} \ No newline at end of file +} diff --git a/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs b/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs index 991571904b..a5294c5eb7 100644 --- a/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs +++ b/src/Shared/HttpSys/RequestProcessing/HeaderEncoding.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Text; namespace Microsoft.AspNetCore.HttpSys.Internal @@ -14,16 +15,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal internal static unsafe string GetString(byte* pBytes, int byteCount) { - // net451: return new string(pBytes, 0, byteCount, Encoding); - - var charCount = Encoding.GetCharCount(pBytes, byteCount); - var chars = new char[charCount]; - fixed (char* pChars = chars) - { - var count = Encoding.GetChars(pBytes, byteCount, pChars, charCount); - System.Diagnostics.Debug.Assert(count == charCount); - } - return new string(chars); + return Encoding.GetString(new ReadOnlySpan<byte>(pBytes, byteCount)); } internal static byte[] GetBytes(string myString) diff --git a/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs b/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs index 4108d901e2..790b858b3b 100644 --- a/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs +++ b/src/Shared/HttpSys/RequestProcessing/NativeRequestContext.cs @@ -2,6 +2,7 @@ // 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.Collections.Generic; using System.Collections.Immutable; using System.Collections.ObjectModel; @@ -17,24 +18,45 @@ namespace Microsoft.AspNetCore.HttpSys.Internal internal unsafe class NativeRequestContext : IDisposable { private const int AlignmentPadding = 8; + private const int DefaultBufferSize = 4096 - AlignmentPadding; private IntPtr _originalBufferAddress; private HttpApiTypes.HTTP_REQUEST* _nativeRequest; - private byte[] _backingBuffer; + private IMemoryOwner<byte> _backingBuffer; + private MemoryHandle _memoryHandle; private int _bufferAlignment; private SafeNativeOverlapped _nativeOverlapped; private bool _permanentlyPinned; + private bool _disposed; // To be used by HttpSys - internal NativeRequestContext(SafeNativeOverlapped nativeOverlapped, - int bufferAlignment, - HttpApiTypes.HTTP_REQUEST* nativeRequest, - byte[] backingBuffer, - ulong requestId) + internal NativeRequestContext(SafeNativeOverlapped nativeOverlapped, MemoryPool<Byte> memoryPool, uint? bufferSize, ulong requestId) { _nativeOverlapped = nativeOverlapped; - _bufferAlignment = bufferAlignment; - _nativeRequest = nativeRequest; - _backingBuffer = backingBuffer; + + // TODO: + // Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors + // are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on + // virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In + // these cases the buffer alignment may cause reading values at invalid offset. Setting buffer + // alignment to 0 for now. + // + // _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07); + _bufferAlignment = 0; + + var newSize = (int)(bufferSize ?? DefaultBufferSize) + AlignmentPadding; + if (newSize <= memoryPool.MaxBufferSize) + { + _backingBuffer = memoryPool.Rent(newSize); + } + else + { + // No size limit + _backingBuffer = MemoryPool<byte>.Shared.Rent(newSize); + } + _backingBuffer.Memory.Span.Fill(0);// Zero the buffer + _memoryHandle = _backingBuffer.Memory.Pin(); + _nativeRequest = (HttpApiTypes.HTTP_REQUEST*)((long)_memoryHandle.Pointer + _bufferAlignment); + RequestId = requestId; } @@ -94,15 +116,17 @@ namespace Microsoft.AspNetCore.HttpSys.Internal internal uint Size { - get { return (uint)_backingBuffer.Length - AlignmentPadding; } + get { return (uint)_backingBuffer.Memory.Length - AlignmentPadding; } } // ReleasePins() should be called exactly once. It must be called before Dispose() is called, which means it must be called // before an object (Request) which closes the RequestContext on demand is returned to the application. internal void ReleasePins() { - Debug.Assert(_nativeRequest != null || _backingBuffer == null, "RequestContextBase::ReleasePins()|ReleasePins() called twice."); + Debug.Assert(_nativeRequest != null, "RequestContextBase::ReleasePins()|ReleasePins() called twice."); _originalBufferAddress = (IntPtr)_nativeRequest; + _memoryHandle.Dispose(); + _memoryHandle = default; _nativeRequest = null; _nativeOverlapped?.Dispose(); _nativeOverlapped = null; @@ -110,8 +134,14 @@ namespace Microsoft.AspNetCore.HttpSys.Internal public virtual void Dispose() { - Debug.Assert(_nativeRequest == null, "RequestContextBase::Dispose()|Dispose() called before ReleasePins()."); - _nativeOverlapped?.Dispose(); + if (!_disposed) + { + _disposed = true; + Debug.Assert(_nativeRequest == null, "RequestContextBase::Dispose()|Dispose() called before ReleasePins()."); + _nativeOverlapped?.Dispose(); + _memoryHandle.Dispose(); + _backingBuffer.Dispose(); + } } // These methods require the HTTP_REQUEST to still be pinned in its original location. @@ -272,7 +302,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } else { - fixed (byte* pMemoryBlob = _backingBuffer) + fixed (byte* pMemoryBlob = _backingBuffer.Memory.Span) { var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment); long fixup = pMemoryBlob - (byte*)_originalBufferAddress; @@ -306,7 +336,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal else { // Return value. - fixed (byte* pMemoryBlob = _backingBuffer) + fixed (byte* pMemoryBlob = _backingBuffer.Memory.Span) { var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment); long fixup = pMemoryBlob - (byte*)_originalBufferAddress; @@ -366,7 +396,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } else { - fixed (byte* pMemoryBlob = _backingBuffer) + fixed (byte* pMemoryBlob = _backingBuffer.Memory.Span) { var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment); return GetEndPointHelper(localEndpoint, request, pMemoryBlob); @@ -426,7 +456,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } else { - fixed (byte* pMemoryBlob = _backingBuffer) + fixed (byte* pMemoryBlob = _backingBuffer.Memory.Span) { var request = (HttpApiTypes.HTTP_REQUEST*)(pMemoryBlob + _bufferAlignment); long fixup = pMemoryBlob - (byte*)_originalBufferAddress; @@ -490,7 +520,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } else { - fixed (byte* pMemoryBlob = _backingBuffer) + fixed (byte* pMemoryBlob = _backingBuffer.Memory.Span) { var request = (HttpApiTypes.HTTP_REQUEST_V2*)(pMemoryBlob + _bufferAlignment); return GetRequestInfo(_originalBufferAddress, request); @@ -514,7 +544,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal var offset = (long)requestInfo.pInfo - (long)baseAddress; info.Add( (int)requestInfo.InfoType, - new ReadOnlyMemory<byte>(_backingBuffer, (int)offset, (int)requestInfo.InfoLength)); + _backingBuffer.Memory.Slice((int)offset, (int)requestInfo.InfoLength)); } return new ReadOnlyDictionary<int, ReadOnlyMemory<byte>>(info); @@ -528,7 +558,7 @@ namespace Microsoft.AspNetCore.HttpSys.Internal } else { - fixed (byte* pMemoryBlob = _backingBuffer) + fixed (byte* pMemoryBlob = _backingBuffer.Memory.Span) { var request = (HttpApiTypes.HTTP_REQUEST_V2*)(pMemoryBlob + _bufferAlignment); return GetClientCertificate(_originalBufferAddress, request); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/BufferExtensions.cs b/src/Shared/ServerInfrastructure/BufferExtensions.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http/BufferExtensions.cs rename to src/Shared/ServerInfrastructure/BufferExtensions.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/BufferWriter.cs b/src/Shared/ServerInfrastructure/BufferWriter.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/BufferWriter.cs rename to src/Shared/ServerInfrastructure/BufferWriter.cs diff --git a/src/Servers/Kestrel/shared/DuplexPipe.cs b/src/Shared/ServerInfrastructure/DuplexPipe.cs similarity index 96% rename from src/Servers/Kestrel/shared/DuplexPipe.cs rename to src/Shared/ServerInfrastructure/DuplexPipe.cs index 1c5896fc0d..cee167b20b 100644 --- a/src/Servers/Kestrel/shared/DuplexPipe.cs +++ b/src/Shared/ServerInfrastructure/DuplexPipe.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All rights reserved. +// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace System.IO.Pipelines diff --git a/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs b/src/Shared/ServerInfrastructure/DuplexPipeStream.cs similarity index 71% rename from src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs rename to src/Shared/ServerInfrastructure/DuplexPipeStream.cs index b81a5e8869..7a2dfdf362 100644 --- a/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs +++ b/src/Shared/ServerInfrastructure/DuplexPipeStream.cs @@ -152,78 +152,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = ReadAsync(buffer, offset, count, default, state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(ReadAsync(buffer, offset, count), callback, state); } public override int EndRead(IAsyncResult asyncResult) { - return ((Task<int>)asyncResult).GetAwaiter().GetResult(); - } - - private Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<int>(state); - var task = ReadAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<int>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(task2.Result); - } - }, tcs, cancellationToken); - return tcs.Task; + return TaskToApm.End<int>(asyncResult); } public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = WriteAsync(buffer, offset, count, default, state); - if (callback != null) - { - task.ContinueWith(t => callback.Invoke(t)); - } - return task; + return TaskToApm.Begin(WriteAsync(buffer, offset, count), callback, state); } public override void EndWrite(IAsyncResult asyncResult) { - ((Task<object>)asyncResult).GetAwaiter().GetResult(); - } - - private Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken, object state) - { - var tcs = new TaskCompletionSource<object>(state); - var task = WriteAsync(buffer, offset, count, cancellationToken); - task.ContinueWith((task2, state2) => - { - var tcs2 = (TaskCompletionSource<object>)state2; - if (task2.IsCanceled) - { - tcs2.SetCanceled(); - } - else if (task2.IsFaulted) - { - tcs2.SetException(task2.Exception); - } - else - { - tcs2.SetResult(null); - } - }, tcs, cancellationToken); - return tcs.Task; + TaskToApm.End(asyncResult); } } } diff --git a/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStreamAdapter.cs b/src/Shared/ServerInfrastructure/DuplexPipeStreamAdapter.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStreamAdapter.cs rename to src/Shared/ServerInfrastructure/DuplexPipeStreamAdapter.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Bitshifter.cs b/src/Shared/ServerInfrastructure/Http2/Bitshifter.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Bitshifter.cs rename to src/Shared/ServerInfrastructure/Http2/Bitshifter.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2ConnectionErrorException.cs b/src/Shared/ServerInfrastructure/Http2/Http2ConnectionErrorException.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2ConnectionErrorException.cs rename to src/Shared/ServerInfrastructure/Http2/Http2ConnectionErrorException.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2ContinuationFrameFlags.cs b/src/Shared/ServerInfrastructure/Http2/Http2ContinuationFrameFlags.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2ContinuationFrameFlags.cs rename to src/Shared/ServerInfrastructure/Http2/Http2ContinuationFrameFlags.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2DataFrameFlags.cs b/src/Shared/ServerInfrastructure/Http2/Http2DataFrameFlags.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2DataFrameFlags.cs rename to src/Shared/ServerInfrastructure/Http2/Http2DataFrameFlags.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2ErrorCode.cs b/src/Shared/ServerInfrastructure/Http2/Http2ErrorCode.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2ErrorCode.cs rename to src/Shared/ServerInfrastructure/Http2/Http2ErrorCode.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Continuation.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.Continuation.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Continuation.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.Continuation.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Data.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.Data.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Data.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.Data.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.GoAway.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.GoAway.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.GoAway.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.GoAway.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Headers.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.Headers.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Headers.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.Headers.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Ping.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.Ping.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Ping.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.Ping.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Priority.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.Priority.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Priority.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.Priority.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.RstStream.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.RstStream.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.RstStream.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.RstStream.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Settings.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.Settings.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Settings.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.Settings.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.WindowUpdate.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.WindowUpdate.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.WindowUpdate.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.WindowUpdate.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.cs b/src/Shared/ServerInfrastructure/Http2/Http2Frame.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.cs rename to src/Shared/ServerInfrastructure/Http2/Http2Frame.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameReader.cs b/src/Shared/ServerInfrastructure/Http2/Http2FrameReader.cs similarity index 92% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameReader.cs rename to src/Shared/ServerInfrastructure/Http2/Http2FrameReader.cs index 8437ad334a..5762b4a671 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameReader.cs +++ b/src/Shared/ServerInfrastructure/Http2/Http2FrameReader.cs @@ -6,7 +6,6 @@ using System.Buffers; using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 { @@ -31,27 +30,27 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 public const int SettingSize = 6; // 2 bytes for the id, 4 bytes for the value. - public static bool ReadFrame(in ReadOnlySequence<byte> readableBuffer, Http2Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload) + public static bool TryReadFrame(ref ReadOnlySequence<byte> buffer, Http2Frame frame, uint maxFrameSize, out ReadOnlySequence<byte> framePayload) { framePayload = ReadOnlySequence<byte>.Empty; - if (readableBuffer.Length < HeaderLength) + if (buffer.Length < HeaderLength) { return false; } - var headerSlice = readableBuffer.Slice(0, HeaderLength); + var headerSlice = buffer.Slice(0, HeaderLength); var header = headerSlice.ToSpan(); var payloadLength = (int)Bitshifter.ReadUInt24BigEndian(header); if (payloadLength > maxFrameSize) { - throw new Http2ConnectionErrorException(CoreStrings.FormatHttp2ErrorFrameOverLimit(payloadLength, maxFrameSize), Http2ErrorCode.FRAME_SIZE_ERROR); + throw new Http2ConnectionErrorException(SharedStrings.FormatHttp2ErrorFrameOverLimit(payloadLength, maxFrameSize), Http2ErrorCode.FRAME_SIZE_ERROR); } // Make sure the whole frame is buffered var frameLength = HeaderLength + payloadLength; - if (readableBuffer.Length < frameLength) + if (buffer.Length < frameLength) { return false; } @@ -61,10 +60,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 frame.Flags = header[FlagsOffset]; frame.StreamId = (int)Bitshifter.ReadUInt31BigEndian(header.Slice(StreamIdOffset)); - var extendedHeaderLength = ReadExtendedFields(frame, readableBuffer); + var extendedHeaderLength = ReadExtendedFields(frame, buffer); // The remaining payload minus the extra fields - framePayload = readableBuffer.Slice(HeaderLength + extendedHeaderLength, payloadLength - extendedHeaderLength); + framePayload = buffer.Slice(HeaderLength + extendedHeaderLength, payloadLength - extendedHeaderLength); + buffer = buffer.Slice(framePayload.End); return true; } @@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 if (extendedHeaderLength > frame.PayloadLength) { throw new Http2ConnectionErrorException( - CoreStrings.FormatHttp2ErrorUnexpectedFrameLength(frame.Type, expectedLength: extendedHeaderLength), Http2ErrorCode.FRAME_SIZE_ERROR); + SharedStrings.FormatHttp2ErrorUnexpectedFrameLength(frame.Type, expectedLength: extendedHeaderLength), Http2ErrorCode.FRAME_SIZE_ERROR); } var extendedHeaders = readableBuffer.Slice(HeaderLength, extendedHeaderLength).ToSpan(); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameType.cs b/src/Shared/ServerInfrastructure/Http2/Http2FrameType.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameType.cs rename to src/Shared/ServerInfrastructure/Http2/Http2FrameType.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersFrameFlags.cs b/src/Shared/ServerInfrastructure/Http2/Http2HeadersFrameFlags.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersFrameFlags.cs rename to src/Shared/ServerInfrastructure/Http2/Http2HeadersFrameFlags.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2PeerSetting.cs b/src/Shared/ServerInfrastructure/Http2/Http2PeerSetting.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2PeerSetting.cs rename to src/Shared/ServerInfrastructure/Http2/Http2PeerSetting.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2PeerSettings.cs b/src/Shared/ServerInfrastructure/Http2/Http2PeerSettings.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2PeerSettings.cs rename to src/Shared/ServerInfrastructure/Http2/Http2PeerSettings.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2PingFrameFlags.cs b/src/Shared/ServerInfrastructure/Http2/Http2PingFrameFlags.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2PingFrameFlags.cs rename to src/Shared/ServerInfrastructure/Http2/Http2PingFrameFlags.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2SettingsFrameFlags.cs b/src/Shared/ServerInfrastructure/Http2/Http2SettingsFrameFlags.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2SettingsFrameFlags.cs rename to src/Shared/ServerInfrastructure/Http2/Http2SettingsFrameFlags.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2SettingsParameter.cs b/src/Shared/ServerInfrastructure/Http2/Http2SettingsParameter.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2SettingsParameter.cs rename to src/Shared/ServerInfrastructure/Http2/Http2SettingsParameter.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2SettingsParameterOutOfRangeException.cs b/src/Shared/ServerInfrastructure/Http2/Http2SettingsParameterOutOfRangeException.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2SettingsParameterOutOfRangeException.cs rename to src/Shared/ServerInfrastructure/Http2/Http2SettingsParameterOutOfRangeException.cs diff --git a/src/Servers/Kestrel/Core/src/Internal/MemoryPoolExtensions.cs b/src/Shared/ServerInfrastructure/MemoryPoolExtensions.cs similarity index 100% rename from src/Servers/Kestrel/Core/src/Internal/MemoryPoolExtensions.cs rename to src/Shared/ServerInfrastructure/MemoryPoolExtensions.cs diff --git a/src/Shared/ServerInfrastructure/ReadMe.md b/src/Shared/ServerInfrastructure/ReadMe.md new file mode 100644 index 0000000000..a23cac13d7 --- /dev/null +++ b/src/Shared/ServerInfrastructure/ReadMe.md @@ -0,0 +1 @@ +This folder contains shared product code that is also used with the Http2Cat test framework. diff --git a/src/Shared/ServerInfrastructure/SharedStrings.resx b/src/Shared/ServerInfrastructure/SharedStrings.resx new file mode 100644 index 0000000000..e6fe3d4ebe --- /dev/null +++ b/src/Shared/ServerInfrastructure/SharedStrings.resx @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="Http2ErrorUnexpectedFrameLength" xml:space="preserve"> + <value>The client sent a {frameType} frame with length different than {expectedLength}.</value> + </data> + <data name="Http2ErrorFrameOverLimit" xml:space="preserve"> + <value>The received frame size of {size} exceeds the limit {limit}.</value> + </data> +</root> \ No newline at end of file diff --git a/src/Shared/ServerInfrastructure/SslDuplexPipe.cs b/src/Shared/ServerInfrastructure/SslDuplexPipe.cs new file mode 100644 index 0000000000..d53ced0031 --- /dev/null +++ b/src/Shared/ServerInfrastructure/SslDuplexPipe.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.IO.Pipelines; +using System.Net.Security; +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal; + +namespace Microsoft.AspNetCore.Server.Kestrel.Https.Internal +{ + internal class SslDuplexPipe : DuplexPipeStreamAdapter<SslStream> + { + public SslDuplexPipe(IDuplexPipe transport, StreamPipeReaderOptions readerOptions, StreamPipeWriterOptions writerOptions) + : this(transport, readerOptions, writerOptions, s => new SslStream(s)) + { + } + + public SslDuplexPipe(IDuplexPipe transport, StreamPipeReaderOptions readerOptions, StreamPipeWriterOptions writerOptions, Func<Stream, SslStream> factory) : + base(transport, readerOptions, writerOptions, factory) + { + } + } +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs b/src/Shared/ServerInfrastructure/StringUtilities.cs similarity index 99% rename from src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs rename to src/Shared/ServerInfrastructure/StringUtilities.cs index aea8290b66..2a12b9893b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/StringUtilities.cs +++ b/src/Shared/ServerInfrastructure/StringUtilities.cs @@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure } [MethodImpl(MethodImplOptions.AggressiveOptimization)] - public unsafe static bool BytesOrdinalEqualsStringAndAscii(string previousValue, Span<byte> newValue) + public unsafe static bool BytesOrdinalEqualsStringAndAscii(string previousValue, ReadOnlySpan<byte> newValue) { // previousValue is a previously materialized string which *must* have already passed validation. Debug.Assert(IsValidHeaderString(previousValue)); diff --git a/src/Shared/Shared.sln b/src/Shared/Shared.sln new file mode 100644 index 0000000000..b627de76e6 --- /dev/null +++ b/src/Shared/Shared.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 16 +VisualStudioVersion = 16.0.0.0 +MinimumVisualStudioVersion = 16.0.0.0 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Shared.Tests", "test\Shared.Tests\Microsoft.AspNetCore.Shared.Tests.csproj", "{06CD38EF-7733-4284-B3E4-825B6B63E1DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {06CD38EF-7733-4284-B3E4-825B6B63E1DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06CD38EF-7733-4284-B3E4-825B6B63E1DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06CD38EF-7733-4284-B3E4-825B6B63E1DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06CD38EF-7733-4284-B3E4-825B6B63E1DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9B7E5B1E-6E6D-4185-9088-2C7C779C6AB2} + EndGlobalSection +EndGlobal diff --git a/src/Shared/StackTrace/ExceptionDetails/ExceptionDetailsProvider.cs b/src/Shared/StackTrace/ExceptionDetails/ExceptionDetailsProvider.cs index 2d1dd20710..340fd68743 100644 --- a/src/Shared/StackTrace/ExceptionDetails/ExceptionDetailsProvider.cs +++ b/src/Shared/StackTrace/ExceptionDetails/ExceptionDetailsProvider.cs @@ -7,17 +7,20 @@ using System.IO; using System.Linq; using System.Reflection; using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; namespace Microsoft.Extensions.StackTrace.Sources { internal class ExceptionDetailsProvider { private readonly IFileProvider _fileProvider; + private readonly ILogger _logger; private readonly int _sourceCodeLineCount; - public ExceptionDetailsProvider(IFileProvider fileProvider, int sourceCodeLineCount) + public ExceptionDetailsProvider(IFileProvider fileProvider, ILogger logger, int sourceCodeLineCount) { _fileProvider = fileProvider; + _logger = logger; _sourceCodeLineCount = sourceCodeLineCount; } @@ -30,15 +33,27 @@ namespace Microsoft.Extensions.StackTrace.Sources yield return new ExceptionDetails { Error = ex, - StackFrames = StackTraceHelper.GetFrames(ex) - .Select(frame => GetStackFrameSourceCodeInfo( - frame.MethodDisplayInfo.ToString(), - frame.FilePath, - frame.LineNumber)) + StackFrames = GetStackFrames(ex), }; } } + private IEnumerable<StackFrameSourceCodeInfo> GetStackFrames(Exception original) + { + var stackFrames = StackTraceHelper.GetFrames(original, out var exception) + .Select(frame => GetStackFrameSourceCodeInfo( + frame.MethodDisplayInfo.ToString(), + frame.FilePath, + frame.LineNumber)); + + if (exception != null) + { + _logger?.FailedToReadStackTraceInfo(exception); + } + + return stackFrames; + } + private static IEnumerable<Exception> FlattenAndReverseExceptionTree(Exception ex) { // ReflectionTypeLoadException is special because the details are in diff --git a/src/Shared/StackTrace/ExceptionDetails/LoggerExtensions.cs b/src/Shared/StackTrace/ExceptionDetails/LoggerExtensions.cs new file mode 100644 index 0000000000..17ef3a944c --- /dev/null +++ b/src/Shared/StackTrace/ExceptionDetails/LoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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 Microsoft.Extensions.Logging; + +namespace Microsoft.Extensions.StackTrace.Sources +{ + internal static class LoggerExtensions + { + private static readonly Action<ILogger, Exception> _failedToReadStackFrameInfo; + + static LoggerExtensions() + { + _failedToReadStackFrameInfo = LoggerMessage.Define( + logLevel: LogLevel.Debug, + eventId: new EventId(0, "FailedToReadStackTraceInfo"), + formatString: "Failed to read stack trace information for exception."); + } + + public static void FailedToReadStackTraceInfo(this ILogger logger, Exception exception) + { + _failedToReadStackFrameInfo(logger, exception); + } + } +} diff --git a/src/Shared/StackTrace/StackFrame/MethodDisplayInfo.cs b/src/Shared/StackTrace/StackFrame/MethodDisplayInfo.cs index b1c0ccc188..8079f96072 100644 --- a/src/Shared/StackTrace/StackFrame/MethodDisplayInfo.cs +++ b/src/Shared/StackTrace/StackFrame/MethodDisplayInfo.cs @@ -33,7 +33,7 @@ namespace Microsoft.Extensions.StackTrace.Sources builder.Append(GenericArguments); builder.Append("("); - builder.Append(string.Join(", ", Parameters.Select(p => p.ToString()))); + builder.AppendJoin(", ", Parameters.Select(p => p.ToString())); builder.Append(")"); if (!string.IsNullOrEmpty(SubMethod)) diff --git a/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs b/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs index 1074097aa9..ae35c4e0b1 100644 --- a/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs +++ b/src/Shared/StackTrace/StackFrame/StackTraceHelper.cs @@ -15,12 +15,13 @@ namespace Microsoft.Extensions.StackTrace.Sources { internal class StackTraceHelper { - public static IList<StackFrameInfo> GetFrames(Exception exception) + public static IList<StackFrameInfo> GetFrames(Exception exception, out AggregateException error) { var frames = new List<StackFrameInfo>(); if (exception == null) { + error = default; return frames; } @@ -32,9 +33,12 @@ namespace Microsoft.Extensions.StackTrace.Sources if (stackFrames == null) { + error = default; return frames; } + List<Exception> exceptions = null; + for (var i = 0; i < stackFrames.Length; i++) { var frame = stackFrames[i]; @@ -56,14 +60,33 @@ namespace Microsoft.Extensions.StackTrace.Sources if (string.IsNullOrEmpty(stackFrame.FilePath)) { - // .NET Framework and older versions of mono don't support portable PDBs - // so we read it manually to get file name and line information - portablePdbReader.PopulateStackFrame(stackFrame, method, frame.GetILOffset()); + try + { + // .NET Framework and older versions of mono don't support portable PDBs + // so we read it manually to get file name and line information + portablePdbReader.PopulateStackFrame(stackFrame, method, frame.GetILOffset()); + } + catch (Exception ex) + { + if (exceptions is null) + { + exceptions = new List<Exception>(); + } + + exceptions.Add(ex); + } } frames.Add(stackFrame); } + if (exceptions != null) + { + error = new AggregateException(exceptions); + return frames; + } + + error = default; return frames; } } diff --git a/src/Shared/TaskToApm.cs b/src/Shared/TaskToApm.cs new file mode 100644 index 0000000000..3a05eb6b42 --- /dev/null +++ b/src/Shared/TaskToApm.cs @@ -0,0 +1,121 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Helper methods for using Tasks to implement the APM pattern. +// +// Example usage, wrapping a Task<int>-returning FooAsync method with Begin/EndFoo methods: +// +// public IAsyncResult BeginFoo(..., AsyncCallback callback, object state) => +// TaskToApm.Begin(FooAsync(...), callback, state); +// +// public int EndFoo(IAsyncResult asyncResult) => +// TaskToApm.End<int>(asyncResult); + +#nullable enable +using System.Diagnostics; + +namespace System.Threading.Tasks +{ + /// <summary> + /// Provides support for efficiently using Tasks to implement the APM (Begin/End) pattern. + /// </summary> + internal static class TaskToApm + { + /// <summary> + /// Marshals the Task as an IAsyncResult, using the supplied callback and state + /// to implement the APM pattern. + /// </summary> + /// <param name="task">The Task to be marshaled.</param> + /// <param name="callback">The callback to be invoked upon completion.</param> + /// <param name="state">The state to be stored in the IAsyncResult.</param> + /// <returns>An IAsyncResult to represent the task's asynchronous operation.</returns> + public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state) => + new TaskAsyncResult(task, state, callback); + + /// <summary>Processes an IAsyncResult returned by Begin.</summary> + /// <param name="asyncResult">The IAsyncResult to unwrap.</param> + public static void End(IAsyncResult asyncResult) + { + if (asyncResult is TaskAsyncResult twar) + { + twar._task.GetAwaiter().GetResult(); + return; + } + + throw new ArgumentNullException(); + } + + /// <summary>Processes an IAsyncResult returned by Begin.</summary> + /// <param name="asyncResult">The IAsyncResult to unwrap.</param> + public static TResult End<TResult>(IAsyncResult asyncResult) + { + if (asyncResult is TaskAsyncResult twar && twar._task is Task<TResult> task) + { + return task.GetAwaiter().GetResult(); + } + + throw new ArgumentNullException(); + } + + /// <summary>Provides a simple IAsyncResult that wraps a Task.</summary> + /// <remarks> + /// We could use the Task as the IAsyncResult if the Task's AsyncState is the same as the object state, + /// but that's very rare, in particular in a situation where someone cares about allocation, and always + /// using TaskAsyncResult simplifies things and enables additional optimizations. + /// </remarks> + internal sealed class TaskAsyncResult : IAsyncResult + { + /// <summary>The wrapped Task.</summary> + internal readonly Task _task; + /// <summary>Callback to invoke when the wrapped task completes.</summary> + private readonly AsyncCallback? _callback; + + /// <summary>Initializes the IAsyncResult with the Task to wrap and the associated object state.</summary> + /// <param name="task">The Task to wrap.</param> + /// <param name="state">The new AsyncState value.</param> + /// <param name="callback">Callback to invoke when the wrapped task completes.</param> + internal TaskAsyncResult(Task task, object? state, AsyncCallback? callback) + { + Debug.Assert(task != null); + _task = task; + AsyncState = state; + + if (task.IsCompleted) + { + // Synchronous completion. Invoke the callback. No need to store it. + CompletedSynchronously = true; + callback?.Invoke(this); + } + else if (callback != null) + { + // Asynchronous completion, and we have a callback; schedule it. We use OnCompleted rather than ContinueWith in + // order to avoid running synchronously if the task has already completed by the time we get here but still run + // synchronously as part of the task's completion if the task completes after (the more common case). + _callback = callback; + _task.ConfigureAwait(continueOnCapturedContext: false) + .GetAwaiter() + .OnCompleted(InvokeCallback); // allocates a delegate, but avoids a closure + } + } + + /// <summary>Invokes the callback.</summary> + private void InvokeCallback() + { + Debug.Assert(!CompletedSynchronously); + Debug.Assert(_callback != null); + _callback.Invoke(this); + } + + /// <summary>Gets a user-defined object that qualifies or contains information about an asynchronous operation.</summary> + public object? AsyncState { get; } + /// <summary>Gets a value that indicates whether the asynchronous operation completed synchronously.</summary> + /// <remarks>This is set lazily based on whether the <see cref="_task"/> has completed by the time this object is created.</remarks> + public bool CompletedSynchronously { get; } + /// <summary>Gets a value that indicates whether the asynchronous operation has completed.</summary> + public bool IsCompleted => _task.IsCompleted; + /// <summary>Gets a <see cref="WaitHandle"/> that is used to wait for an asynchronous operation to complete.</summary> + public WaitHandle AsyncWaitHandle => ((IAsyncResult)_task).AsyncWaitHandle; + } + } +} \ No newline at end of file diff --git a/src/Shared/test/Shared.Tests/Http2/DynamicTableTest.cs b/src/Shared/test/Shared.Tests/Http2/DynamicTableTest.cs new file mode 100644 index 0000000000..fe0e4c7ec5 --- /dev/null +++ b/src/Shared/test/Shared.Tests/Http2/DynamicTableTest.cs @@ -0,0 +1,255 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.Http.HPack; +using System.Reflection; +using System.Text; +using Xunit; + +namespace System.Net.Http.Unit.Tests.HPack +{ + public class DynamicTableTest + { + private readonly HeaderField _header1 = new HeaderField(Encoding.ASCII.GetBytes("header-1"), Encoding.ASCII.GetBytes("value1")); + private readonly HeaderField _header2 = new HeaderField(Encoding.ASCII.GetBytes("header-02"), Encoding.ASCII.GetBytes("value_2")); + + [Fact] + public void DynamicTable_IsInitiallyEmpty() + { + DynamicTable dynamicTable = new DynamicTable(4096); + Assert.Equal(0, dynamicTable.Count); + Assert.Equal(0, dynamicTable.Size); + Assert.Equal(4096, dynamicTable.MaxSize); + } + + [Fact] + public void DynamicTable_Count_IsNumberOfEntriesInDynamicTable() + { + DynamicTable dynamicTable = new DynamicTable(4096); + + dynamicTable.Insert(_header1.Name, _header1.Value); + Assert.Equal(1, dynamicTable.Count); + + dynamicTable.Insert(_header2.Name, _header2.Value); + Assert.Equal(2, dynamicTable.Count); + } + + [Fact] + public void DynamicTable_Size_IsCurrentDynamicTableSize() + { + DynamicTable dynamicTable = new DynamicTable(4096); + Assert.Equal(0, dynamicTable.Size); + + dynamicTable.Insert(_header1.Name, _header1.Value); + Assert.Equal(_header1.Length, dynamicTable.Size); + + dynamicTable.Insert(_header2.Name, _header2.Value); + Assert.Equal(_header1.Length + _header2.Length, dynamicTable.Size); + } + + [Fact] + public void DynamicTable_FirstEntry_IsMostRecentEntry() + { + DynamicTable dynamicTable = new DynamicTable(4096); + dynamicTable.Insert(_header1.Name, _header1.Value); + dynamicTable.Insert(_header2.Name, _header2.Value); + + VerifyTableEntries(dynamicTable, _header2, _header1); + } + + [Fact] + public void BoundsCheck_ThrowsIndexOutOfRangeException() + { + DynamicTable dynamicTable = new DynamicTable(4096); + Assert.Throws<IndexOutOfRangeException>(() => dynamicTable[0]); + + dynamicTable.Insert(_header1.Name, _header1.Value); + Assert.Throws<IndexOutOfRangeException>(() => dynamicTable[1]); + } + + [Fact] + public void DynamicTable_InsertEntryLargerThanMaxSize_NoOp() + { + DynamicTable dynamicTable = new DynamicTable(_header1.Length - 1); + dynamicTable.Insert(_header1.Name, _header1.Value); + + Assert.Equal(0, dynamicTable.Count); + Assert.Equal(0, dynamicTable.Size); + } + + [Fact] + public void DynamicTable_InsertEntryLargerThanRemainingSpace_NoOp() + { + DynamicTable dynamicTable = new DynamicTable(_header1.Length); + dynamicTable.Insert(_header1.Name, _header1.Value); + + VerifyTableEntries(dynamicTable, _header1); + + dynamicTable.Insert(_header2.Name, _header2.Value); + + Assert.Equal(0, dynamicTable.Count); + Assert.Equal(0, dynamicTable.Size); + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(2)] + [InlineData(3)] + public void DynamicTable_WrapsRingBuffer_Success(int targetInsertIndex) + { + FieldInfo insertIndexField = typeof(DynamicTable).GetField("_insertIndex", BindingFlags.NonPublic | BindingFlags.Instance); + DynamicTable table = new DynamicTable(maxSize: 256); + Stack<byte[]> insertedHeaders = new Stack<byte[]>(); + + // Insert into dynamic table until its insert index into its ring buffer loops back to 0. + do + { + InsertOne(); + } + while ((int)insertIndexField.GetValue(table) != 0); + + // Finally loop until the insert index reaches the target. + while ((int)insertIndexField.GetValue(table) != targetInsertIndex) + { + InsertOne(); + } + + void InsertOne() + { + byte[] data = Encoding.ASCII.GetBytes($"header-{insertedHeaders.Count}"); + + insertedHeaders.Push(data); + table.Insert(data, data); + } + + // Now check to see that we can retrieve the remaining headers. + // Some headers will have been evacuated from the table during this process, so we don't exhaust the entire insertedHeaders stack. + Assert.True(table.Count > 0); + Assert.True(table.Count < insertedHeaders.Count); + + for (int i = 0; i < table.Count; ++i) + { + HeaderField dynamicField = table[i]; + byte[] expectedData = insertedHeaders.Pop(); + + Assert.True(expectedData.AsSpan().SequenceEqual(dynamicField.Name)); + Assert.True(expectedData.AsSpan().SequenceEqual(dynamicField.Value)); + } + } + + [Theory] + [MemberData(nameof(CreateResizeData))] + public void DynamicTable_Resize_Success(int initialMaxSize, int finalMaxSize, int insertSize) + { + // This is purely to make it simple to perfectly reach our initial max size to test growing a full but non-wrapping buffer. + Debug.Assert((insertSize % 64) == 0, $"{nameof(insertSize)} must be a multiple of 64 ({nameof(HeaderField)}.{nameof(HeaderField.RfcOverhead)} * 2)"); + + DynamicTable dynamicTable = new DynamicTable(maxSize: initialMaxSize); + int insertedSize = 0; + + while (insertedSize != insertSize) + { + byte[] data = Encoding.ASCII.GetBytes($"header-{dynamicTable.Size}".PadRight(16, ' ')); + Debug.Assert(data.Length == 16); + + dynamicTable.Insert(data, data); + insertedSize += data.Length * 2 + HeaderField.RfcOverhead; + } + + List<HeaderField> headers = new List<HeaderField>(); + + for (int i = 0; i < dynamicTable.Count; ++i) + { + headers.Add(dynamicTable[i]); + } + + dynamicTable.Resize(finalMaxSize); + + int expectedCount = Math.Min(finalMaxSize / 64, headers.Count); + Assert.Equal(expectedCount, dynamicTable.Count); + + for (int i = 0; i < dynamicTable.Count; ++i) + { + Assert.True(headers[i].Name.AsSpan().SequenceEqual(dynamicTable[i].Name)); + Assert.True(headers[i].Value.AsSpan().SequenceEqual(dynamicTable[i].Value)); + } + } + + [Fact] + public void DynamicTable_ResizingEvictsOldestEntries() + { + DynamicTable dynamicTable = new DynamicTable(4096); + dynamicTable.Insert(_header1.Name, _header1.Value); + dynamicTable.Insert(_header2.Name, _header2.Value); + + VerifyTableEntries(dynamicTable, _header2, _header1); + + dynamicTable.Resize(_header2.Length); + + VerifyTableEntries(dynamicTable, _header2); + } + + [Fact] + public void DynamicTable_ResizingToZeroEvictsAllEntries() + { + DynamicTable dynamicTable = new DynamicTable(4096); + dynamicTable.Insert(_header1.Name, _header1.Value); + dynamicTable.Insert(_header2.Name, _header2.Value); + + dynamicTable.Resize(0); + + Assert.Equal(0, dynamicTable.Count); + Assert.Equal(0, dynamicTable.Size); + } + + [Fact] + public void DynamicTable_CanBeResizedToLargerMaxSize() + { + DynamicTable dynamicTable = new DynamicTable(_header1.Length); + dynamicTable.Insert(_header1.Name, _header1.Value); + dynamicTable.Insert(_header2.Name, _header2.Value); + + // _header2 is larger than _header1, so an attempt at inserting it + // would first clear the table then return without actually inserting it, + // given it is larger than the current max size. + Assert.Equal(0, dynamicTable.Count); + Assert.Equal(0, dynamicTable.Size); + + dynamicTable.Resize(dynamicTable.MaxSize + _header2.Length); + dynamicTable.Insert(_header2.Name, _header2.Value); + + VerifyTableEntries(dynamicTable, _header2); + } + + public static IEnumerable<object[]> CreateResizeData() + { + int[] values = new[] { 128, 256, 384, 512 }; + return from initialMaxSize in values + from finalMaxSize in values + from insertSize in values + select new object[] { initialMaxSize, finalMaxSize, insertSize }; + } + + private void VerifyTableEntries(DynamicTable dynamicTable, params HeaderField[] entries) + { + Assert.Equal(entries.Length, dynamicTable.Count); + Assert.Equal(entries.Sum(e => e.Length), dynamicTable.Size); + + for (int i = 0; i < entries.Length; i++) + { + HeaderField headerField = dynamicTable[i]; + + Assert.NotSame(entries[i].Name, headerField.Name); + Assert.Equal(entries[i].Name, headerField.Name); + + Assert.NotSame(entries[i].Value, headerField.Value); + Assert.Equal(entries[i].Value, headerField.Value); + } + } + } +} diff --git a/src/Servers/Kestrel/Core/test/HPackDecoderTests.cs b/src/Shared/test/Shared.Tests/Http2/HPackDecoderTest.cs similarity index 78% rename from src/Servers/Kestrel/Core/test/HPackDecoderTests.cs rename to src/Shared/test/Shared.Tests/Http2/HPackDecoderTest.cs index d9318e01e9..9e80a509b7 100644 --- a/src/Servers/Kestrel/Core/test/HPackDecoderTests.cs +++ b/src/Shared/test/Shared.Tests/Http2/HPackDecoderTest.cs @@ -1,23 +1,23 @@ // 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. +// Licensed under the Apache License, Version 2.0. +// See THIRD-PARTY-NOTICES.TXT in the project root for license information. -using System; using System.Buffers; -using System.Collections.Generic; using System.Linq; +using System.Collections.Generic; using System.Text; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; -using Microsoft.Net.Http.Headers; +using System.Net.Http.HPack; using Xunit; +#if KESTREL +using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; +#endif -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests +namespace System.Net.Http.Unit.Tests.HPack { public class HPackDecoderTests : IHttpHeadersHandler { private const int DynamicTableInitialMaxSize = 4096; - private const int MaxRequestHeaderFieldSize = 8192; + private const int MaxHeaderFieldSize = 8192; // Indexed Header Field Representation - Static Table - Index 2 (:method: GET) private static readonly byte[] _indexedHeaderStatic = new byte[] { 0x82 }; @@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // v a l u e * // 11101110 00111010 00101101 00101111 - private static readonly byte[] _headerValueHuffmanBytes = new byte [] { 0xee, 0x3a, 0x2d, 0x2f }; + private static readonly byte[] _headerValueHuffmanBytes = new byte[] { 0xee, 0x3a, 0x2d, 0x2f }; private static readonly byte[] _headerName = new byte[] { (byte)_headerNameBytes.Length } .Concat(_headerNameBytes) @@ -95,21 +95,24 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests public HPackDecoderTests() { _dynamicTable = new DynamicTable(DynamicTableInitialMaxSize); - _decoder = new HPackDecoder(DynamicTableInitialMaxSize, MaxRequestHeaderFieldSize, _dynamicTable); + _decoder = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize, _dynamicTable); } - void IHttpHeadersHandler.OnHeader(Span<byte> name, Span<byte> value) + void IHttpHeadersHandler.OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value) { - _decodedHeaders[name.GetAsciiStringNonNullCharacters()] = value.GetAsciiStringNonNullCharacters(); + string headerName = Encoding.ASCII.GetString(name); + string headerValue = Encoding.ASCII.GetString(value); + + _decodedHeaders[headerName] = headerValue; } - void IHttpHeadersHandler.OnHeadersComplete() { } + void IHttpHeadersHandler.OnHeadersComplete(bool endStream) { } [Fact] public void DecodesIndexedHeaderField_StaticTable() { - _decoder.Decode(new ReadOnlySequence<byte>(_indexedHeaderStatic), endHeaders: true, handler: this); - Assert.Equal("GET", _decodedHeaders[HeaderNames.Method]); + _decoder.Decode(_indexedHeaderStatic, endHeaders: true, handler: this); + Assert.Equal("GET", _decodedHeaders[":method"]); } [Fact] @@ -119,23 +122,23 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests _dynamicTable.Insert(_headerNameBytes, _headerValueBytes); // Index it - _decoder.Decode(new ReadOnlySequence<byte>(_indexedHeaderDynamic), endHeaders: true, handler: this); + _decoder.Decode(_indexedHeaderDynamic, endHeaders: true, handler: this); Assert.Equal(_headerValueString, _decodedHeaders[_headerNameString]); } [Fact] public void DecodesIndexedHeaderField_OutOfRange_Error() { - var exception = Assert.Throws<HPackDecodingException>(() => - _decoder.Decode(new ReadOnlySequence<byte>(_indexedHeaderDynamic), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.FormatHPackErrorIndexOutOfRange(62), exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => + _decoder.Decode(_indexedHeaderDynamic, endHeaders: true, handler: this)); + Assert.Equal(SR.Format(SR.net_http_hpack_invalid_index, 62), exception.Message); Assert.Empty(_decodedHeaders); } [Fact] public void DecodesLiteralHeaderFieldWithIncrementalIndexing_NewName() { - var encoded = _literalHeaderFieldWithIndexingNewName + byte[] encoded = _literalHeaderFieldWithIndexingNewName .Concat(_headerName) .Concat(_headerValue) .ToArray(); @@ -146,7 +149,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithIncrementalIndexing_NewName_HuffmanEncodedName() { - var encoded = _literalHeaderFieldWithIndexingNewName + byte[] encoded = _literalHeaderFieldWithIndexingNewName .Concat(_headerNameHuffman) .Concat(_headerValue) .ToArray(); @@ -157,7 +160,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithIncrementalIndexing_NewName_HuffmanEncodedValue() { - var encoded = _literalHeaderFieldWithIndexingNewName + byte[] encoded = _literalHeaderFieldWithIndexingNewName .Concat(_headerName) .Concat(_headerValueHuffman) .ToArray(); @@ -168,7 +171,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithIncrementalIndexing_NewName_HuffmanEncodedNameAndValue() { - var encoded = _literalHeaderFieldWithIndexingNewName + byte[] encoded = _literalHeaderFieldWithIndexingNewName .Concat(_headerNameHuffman) .Concat(_headerValueHuffman) .ToArray(); @@ -179,7 +182,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithIncrementalIndexing_IndexedName() { - var encoded = _literalHeaderFieldWithIndexingIndexedName + byte[] encoded = _literalHeaderFieldWithIndexingIndexedName .Concat(_headerValue) .ToArray(); @@ -189,7 +192,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithIncrementalIndexing_IndexedName_HuffmanEncodedValue() { - var encoded = _literalHeaderFieldWithIndexingIndexedName + byte[] encoded = _literalHeaderFieldWithIndexingIndexedName .Concat(_headerValueHuffman) .ToArray(); @@ -203,15 +206,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // 11 1110 (Indexed Name - Index 62 encoded with 6-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) // Index 62 is the first entry in the dynamic table. If there's nothing there, the decoder should throw. - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new ReadOnlySequence<byte>(new byte[] { 0x7e }), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.FormatHPackErrorIndexOutOfRange(62), exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new byte[] { 0x7e }, endHeaders: true, handler: this)); + Assert.Equal(SR.Format(SR.net_http_hpack_invalid_index, 62), exception.Message); Assert.Empty(_decodedHeaders); } [Fact] public void DecodesLiteralHeaderFieldWithoutIndexing_NewName() { - var encoded = _literalHeaderFieldWithoutIndexingNewName + byte[] encoded = _literalHeaderFieldWithoutIndexingNewName .Concat(_headerName) .Concat(_headerValue) .ToArray(); @@ -222,7 +225,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithoutIndexing_NewName_HuffmanEncodedName() { - var encoded = _literalHeaderFieldWithoutIndexingNewName + byte[] encoded = _literalHeaderFieldWithoutIndexingNewName .Concat(_headerNameHuffman) .Concat(_headerValue) .ToArray(); @@ -233,7 +236,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithoutIndexing_NewName_HuffmanEncodedValue() { - var encoded = _literalHeaderFieldWithoutIndexingNewName + byte[] encoded = _literalHeaderFieldWithoutIndexingNewName .Concat(_headerName) .Concat(_headerValueHuffman) .ToArray(); @@ -244,7 +247,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithoutIndexing_NewName_HuffmanEncodedNameAndValue() { - var encoded = _literalHeaderFieldWithoutIndexingNewName + byte[] encoded = _literalHeaderFieldWithoutIndexingNewName .Concat(_headerNameHuffman) .Concat(_headerValueHuffman) .ToArray(); @@ -255,7 +258,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithoutIndexing_IndexedName() { - var encoded = _literalHeaderFieldWithoutIndexingIndexedName + byte[] encoded = _literalHeaderFieldWithoutIndexingIndexedName .Concat(_headerValue) .ToArray(); @@ -265,7 +268,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldWithoutIndexing_IndexedName_HuffmanEncodedValue() { - var encoded = _literalHeaderFieldWithoutIndexingIndexedName + byte[] encoded = _literalHeaderFieldWithoutIndexingIndexedName .Concat(_headerValueHuffman) .ToArray(); @@ -279,15 +282,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // 1111 0010 1111 (Indexed Name - Index 62 encoded with 4-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) // Index 62 is the first entry in the dynamic table. If there's nothing there, the decoder should throw. - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new ReadOnlySequence<byte>(new byte[] { 0x0f, 0x2f }), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.FormatHPackErrorIndexOutOfRange(62), exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new byte[] { 0x0f, 0x2f }, endHeaders: true, handler: this)); + Assert.Equal(SR.Format(SR.net_http_hpack_invalid_index, 62), exception.Message); Assert.Empty(_decodedHeaders); } [Fact] public void DecodesLiteralHeaderFieldNeverIndexed_NewName() { - var encoded = _literalHeaderFieldNeverIndexedNewName + byte[] encoded = _literalHeaderFieldNeverIndexedNewName .Concat(_headerName) .Concat(_headerValue) .ToArray(); @@ -298,7 +301,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldNeverIndexed_NewName_HuffmanEncodedName() { - var encoded = _literalHeaderFieldNeverIndexedNewName + byte[] encoded = _literalHeaderFieldNeverIndexedNewName .Concat(_headerNameHuffman) .Concat(_headerValue) .ToArray(); @@ -309,7 +312,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldNeverIndexed_NewName_HuffmanEncodedValue() { - var encoded = _literalHeaderFieldNeverIndexedNewName + byte[] encoded = _literalHeaderFieldNeverIndexedNewName .Concat(_headerName) .Concat(_headerValueHuffman) .ToArray(); @@ -320,7 +323,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [Fact] public void DecodesLiteralHeaderFieldNeverIndexed_NewName_HuffmanEncodedNameAndValue() { - var encoded = _literalHeaderFieldNeverIndexedNewName + byte[] encoded = _literalHeaderFieldNeverIndexedNewName .Concat(_headerNameHuffman) .Concat(_headerValueHuffman) .ToArray(); @@ -334,7 +337,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // 0001 (Literal Header Field Never Indexed Representation) // 1111 0010 1011 (Indexed Name - Index 58 encoded with 4-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) // Concatenated with value bytes - var encoded = _literalHeaderFieldNeverIndexedIndexedName + byte[] encoded = _literalHeaderFieldNeverIndexedIndexedName .Concat(_headerValue) .ToArray(); @@ -347,7 +350,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // 0001 (Literal Header Field Never Indexed Representation) // 1111 0010 1011 (Indexed Name - Index 58 encoded with 4-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) // Concatenated with Huffman encoded value bytes - var encoded = _literalHeaderFieldNeverIndexedIndexedName + byte[] encoded = _literalHeaderFieldNeverIndexedIndexedName .Concat(_headerValueHuffman) .ToArray(); @@ -361,8 +364,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests // 1111 0010 1111 (Indexed Name - Index 62 encoded with 4-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) // Index 62 is the first entry in the dynamic table. If there's nothing there, the decoder should throw. - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new ReadOnlySequence<byte>(new byte[] { 0x1f, 0x2f }), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.FormatHPackErrorIndexOutOfRange(62), exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new byte[] { 0x1f, 0x2f }, endHeaders: true, handler: this)); + Assert.Equal(SR.Format(SR.net_http_hpack_invalid_index, 62), exception.Message); Assert.Empty(_decodedHeaders); } @@ -374,7 +377,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal(DynamicTableInitialMaxSize, _dynamicTable.MaxSize); - _decoder.Decode(new ReadOnlySequence<byte>(new byte[] { 0x3e }), endHeaders: true, handler: this); + _decoder.Decode(new byte[] { 0x3e }, endHeaders: true, handler: this); Assert.Equal(30, _dynamicTable.MaxSize); Assert.Empty(_decodedHeaders); @@ -388,9 +391,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal(DynamicTableInitialMaxSize, _dynamicTable.MaxSize); - var data = new ReadOnlySequence<byte>(_indexedHeaderStatic.Concat(new byte[] { 0x3e }).ToArray()); - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(data, endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.HPackErrorDynamicTableSizeUpdateNotAtBeginningOfHeaderBlock, exception.Message); + byte[] data = _indexedHeaderStatic.Concat(new byte[] { 0x3e }).ToArray(); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(data, endHeaders: true, handler: this)); + Assert.Equal(SR.net_http_hpack_late_dynamic_table_size_update, exception.Message); } [Fact] @@ -398,14 +401,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { Assert.Equal(DynamicTableInitialMaxSize, _dynamicTable.MaxSize); - _decoder.Decode(new ReadOnlySequence<byte>(_indexedHeaderStatic), endHeaders: false, handler: this); - Assert.Equal("GET", _decodedHeaders[HeaderNames.Method]); + _decoder.Decode(_indexedHeaderStatic, endHeaders: false, handler: this); + Assert.Equal("GET", _decodedHeaders[":method"]); // 001 (Dynamic Table Size Update) // 11110 (30 encoded with 5-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) - var data = new ReadOnlySequence<byte>(new byte[] { 0x3e }); - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(data, endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.HPackErrorDynamicTableSizeUpdateNotAtBeginningOfHeaderBlock, exception.Message); + byte[] data = new byte[] { 0x3e }; + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(data, endHeaders: true, handler: this)); + Assert.Equal(SR.net_http_hpack_late_dynamic_table_size_update, exception.Message); } [Fact] @@ -413,12 +416,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { Assert.Equal(DynamicTableInitialMaxSize, _dynamicTable.MaxSize); - _decoder.Decode(new ReadOnlySequence<byte>(_indexedHeaderStatic), endHeaders: true, handler: this); - Assert.Equal("GET", _decodedHeaders[HeaderNames.Method]); + _decoder.Decode(_indexedHeaderStatic, endHeaders: true, handler: this); + Assert.Equal("GET", _decodedHeaders[":method"]); // 001 (Dynamic Table Size Update) // 11110 (30 encoded with 5-bit prefix - see http://httpwg.org/specs/rfc7541.html#integer.representation) - _decoder.Decode(new ReadOnlySequence<byte>(new byte[] { 0x3e }), endHeaders: true, handler: this); + _decoder.Decode(new byte[] { 0x3e }, endHeaders: true, handler: this); Assert.Equal(30, _dynamicTable.MaxSize); } @@ -431,38 +434,38 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal(DynamicTableInitialMaxSize, _dynamicTable.MaxSize); - var exception = Assert.Throws<HPackDecodingException>(() => - _decoder.Decode(new ReadOnlySequence<byte>(new byte[] { 0x3f, 0xe2, 0x1f }), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.FormatHPackErrorDynamicTableSizeUpdateTooLarge(4097, DynamicTableInitialMaxSize), exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => + _decoder.Decode(new byte[] { 0x3f, 0xe2, 0x1f }, endHeaders: true, handler: this)); + Assert.Equal(SR.Format(SR.net_http_hpack_large_table_size_update, 4097, DynamicTableInitialMaxSize), exception.Message); Assert.Empty(_decodedHeaders); } [Fact] public void DecodesStringLength_GreaterThanLimit_Error() { - var encoded = _literalHeaderFieldWithoutIndexingNewName + byte[] encoded = _literalHeaderFieldWithoutIndexingNewName .Concat(new byte[] { 0xff, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix .ToArray(); - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new ReadOnlySequence<byte>(encoded), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.FormatHPackStringLengthTooLarge(MaxRequestHeaderFieldSize + 1, MaxRequestHeaderFieldSize), exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(encoded, endHeaders: true, handler: this)); + Assert.Equal(SR.Format(SR.net_http_headers_exceeded_length, MaxHeaderFieldSize), exception.Message); Assert.Empty(_decodedHeaders); } [Fact] public void DecodesStringLength_LimitConfigurable() { - var decoder = new HPackDecoder(DynamicTableInitialMaxSize, MaxRequestHeaderFieldSize + 1); - var string8193 = new string('a', MaxRequestHeaderFieldSize + 1); + HPackDecoder decoder = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize + 1); + string string8193 = new string('a', MaxHeaderFieldSize + 1); - var encoded = _literalHeaderFieldWithoutIndexingNewName + byte[] encoded = _literalHeaderFieldWithoutIndexingNewName .Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding .Concat(Encoding.ASCII.GetBytes(string8193)) .Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding .Concat(Encoding.ASCII.GetBytes(string8193)) .ToArray(); - decoder.Decode(new ReadOnlySequence<byte>(encoded), endHeaders: true, handler: this); + decoder.Decode(encoded, endHeaders: true, handler: this); Assert.Equal(string8193, _decodedHeaders[string8193]); } @@ -552,8 +555,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(_incompleteHeaderBlockData))] public void DecodesIncompleteHeaderBlock_Error(byte[] encoded) { - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new ReadOnlySequence<byte>(encoded), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.HPackErrorIncompleteHeaderBlock, exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(encoded, endHeaders: true, handler: this)); + Assert.Equal(SR.net_http_hpack_incomplete_header_block, exception.Message); Assert.Empty(_decodedHeaders); } @@ -586,8 +589,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(_huffmanDecodingErrorData))] public void WrapsHuffmanDecodingExceptionInHPackDecodingException(byte[] encoded) { - var exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(new ReadOnlySequence<byte>(encoded), endHeaders: true, handler: this)); - Assert.Equal(CoreStrings.HPackHuffmanError, exception.Message); + HPackDecodingException exception = Assert.Throws<HPackDecodingException>(() => _decoder.Decode(encoded, endHeaders: true, handler: this)); + Assert.Equal(SR.net_http_hpack_huffman_decode_failed, exception.Message); Assert.IsType<HuffmanDecodingException>(exception.InnerException); Assert.Empty(_decodedHeaders); } @@ -607,7 +610,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal(0, _dynamicTable.Count); Assert.Equal(0, _dynamicTable.Size); - _decoder.Decode(new ReadOnlySequence<byte>(encoded), endHeaders: true, handler: this); + _decoder.Decode(encoded, endHeaders: true, handler: this); Assert.Equal(expectedHeaderValue, _decodedHeaders[expectedHeaderName]); diff --git a/src/Shared/test/Shared.Tests/Http2/HPackIntegerTest.cs b/src/Shared/test/Shared.Tests/Http2/HPackIntegerTest.cs new file mode 100644 index 0000000000..f7362aee4e --- /dev/null +++ b/src/Shared/test/Shared.Tests/Http2/HPackIntegerTest.cs @@ -0,0 +1,129 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Net.Http.HPack; +using Xunit; + +namespace System.Net.Http.Unit.Tests.HPack +{ + public class HPackIntegerTest + { + [Theory] + [MemberData(nameof(IntegerCodecExactSamples))] + public void HPack_IntegerEncode(int value, int bits, byte[] expectedResult) + { + Span<byte> actualResult = new byte[64]; + bool success = IntegerEncoder.Encode(value, bits, actualResult, out int bytesWritten); + + Assert.True(success); + Assert.Equal(expectedResult.Length, bytesWritten); + Assert.True(actualResult.Slice(0, bytesWritten).SequenceEqual(expectedResult)); + } + + [Theory] + [MemberData(nameof(IntegerCodecExactSamples))] + public void HPack_IntegerEncode_ShortBuffer(int value, int bits, byte[] expectedResult) + { + Span<byte> actualResult = new byte[expectedResult.Length - 1]; + bool success = IntegerEncoder.Encode(value, bits, actualResult, out int bytesWritten); + + Assert.False(success); + } + + [Theory] + [MemberData(nameof(IntegerCodecExactSamples))] + public void HPack_IntegerDecode(int expectedResult, int bits, byte[] encoded) + { + IntegerDecoder integerDecoder = new IntegerDecoder(); + + bool finished = integerDecoder.BeginTryDecode(encoded[0], bits, out int actualResult); + + int i = 1; + for (; !finished && i < encoded.Length; ++i) + { + finished = integerDecoder.TryDecode(encoded[i], out actualResult); + } + + Assert.True(finished); + Assert.Equal(encoded.Length, i); + + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void IntegerEncoderDecoderRoundtrips() + { + IntegerDecoder decoder = new IntegerDecoder(); + + for (int i = 0; i < 2048; ++i) + { + for (int prefixLength = 1; prefixLength <= 8; ++prefixLength) + { + Span<byte> integerBytes = stackalloc byte[5]; + Assert.True(IntegerEncoder.Encode(i, prefixLength, integerBytes, out int length)); + + bool decodeResult = decoder.BeginTryDecode(integerBytes[0], prefixLength, out int intResult); + + for (int j = 1; j < length; j++) + { + Assert.False(decodeResult); + decodeResult = decoder.TryDecode(integerBytes[j], out intResult); + } + + Assert.True(decodeResult); + Assert.Equal(i, intResult); + } + } + } + + public static IEnumerable<object[]> IntegerCodecExactSamples() + { + yield return new object[] { 10, 5, new byte[] { 0x0A } }; + yield return new object[] { 1337, 5, new byte[] { 0x1F, 0x9A, 0x0A } }; + yield return new object[] { 42, 8, new byte[] { 0x2A } }; + yield return new object[] { 7, 3, new byte[] { 0x7, 0x0 } }; + yield return new object[] { int.MaxValue, 1, new byte[] { 0x01, 0xfe, 0xff, 0xff, 0xff, 0x07 } }; + yield return new object[] { int.MaxValue, 8, new byte[] { 0xff, 0x80, 0xfe, 0xff, 0xff, 0x07 } }; + } + + [Theory] + [MemberData(nameof(IntegerData_OverMax))] + public void IntegerDecode_Throws_IfMaxExceeded(int prefixLength, byte[] octets) + { + var decoder = new IntegerDecoder(); + var result = decoder.BeginTryDecode(octets[0], prefixLength, out var intResult); + + for (var j = 1; j < octets.Length - 1; j++) + { + Assert.False(decoder.TryDecode(octets[j], out intResult)); + } + + Assert.Throws<HPackDecodingException>(() => decoder.TryDecode(octets[octets.Length - 1], out intResult)); + } + + public static TheoryData<int, byte[]> IntegerData_OverMax + { + get + { + var data = new TheoryData<int, byte[]>(); + + data.Add(1, new byte[] { 0x01, 0xff, 0xff, 0xff, 0xff, 0x07 }); // Int32.MaxValue + 1 + data.Add(1, new byte[] { 0x01, 0xff, 0xff, 0xff, 0xff, 0x08 }); // MSB exceeds maximum + data.Add(1, new byte[] { 0x01, 0xff, 0xff, 0xff, 0xff, 0x80 }); // Undefined since continuation bit set + + data.Add(7, new byte[] { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x08 }); // 1 bit too large + data.Add(7, new byte[] { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F }); + data.Add(7, new byte[] { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80 }); // A continuation byte (0x80) where the byte after it would be too large. + data.Add(7, new byte[] { 0x7F, 0xFF, 0x00 }); // Encoded with 1 byte too many. + + data.Add(8, new byte[] { 0xff, 0x81, 0xfe, 0xff, 0xff, 0x07 }); // Int32.MaxValue + 1 + data.Add(8, new byte[] { 0xff, 0x81, 0xfe, 0xff, 0xff, 0x08 }); // MSB exceeds maximum + data.Add(8, new byte[] { 0xff, 0x81, 0xfe, 0xff, 0xff, 0x80 }); // Undefined since continuation bit set + + return data; + } + } + } +} diff --git a/src/Servers/Kestrel/Core/test/HuffmanTests.cs b/src/Shared/test/Shared.Tests/Http2/HuffmanDecodingTests.cs similarity index 72% rename from src/Servers/Kestrel/Core/test/HuffmanTests.cs rename to src/Shared/test/Shared.Tests/Http2/HuffmanDecodingTests.cs index dfae6afe6e..4383de415b 100644 --- a/src/Servers/Kestrel/Core/test/HuffmanTests.cs +++ b/src/Shared/test/Shared.Tests/Http2/HuffmanDecodingTests.cs @@ -1,15 +1,193 @@ -// 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. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. -using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.HPack; using System.Text; -using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack; using Xunit; -namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests +namespace System.Net.Http.Unit.Tests.HPack { - public class HuffmanTests + public class HuffmanDecodingTests { + // Encoded values are 30 bits at most, so are stored in the table in a uint. + // Convert to ulong here and put the encoded value in the most significant bits. + // This makes the encoding logic below simpler. + private static (ulong code, int bitLength) GetEncodedValue(byte b) + { + (uint code, int bitLength) = Huffman.Encode(b); + return (((ulong)code) << 32, bitLength); + } + + private static int Encode(byte[] source, byte[] destination, bool injectEOS) + { + ulong currentBits = 0; // We can have 7 bits of rollover plus 30 bits for the next encoded value, so use a ulong + int currentBitCount = 0; + int dstOffset = 0; + + for (int i = 0; i < source.Length; i++) + { + (ulong code, int bitLength) = GetEncodedValue(source[i]); + + // inject EOS if instructed to + if (injectEOS) + { + code |= (ulong)0b11111111_11111111_11111111_11111100 << (32 - bitLength); + bitLength += 30; + injectEOS = false; + } + + currentBits |= code >> currentBitCount; + currentBitCount += bitLength; + + while (currentBitCount >= 8) + { + destination[dstOffset++] = (byte)(currentBits >> 56); + currentBits = currentBits << 8; + currentBitCount -= 8; + } + } + + // Fill any trailing bits with ones, per RFC + if (currentBitCount > 0) + { + currentBits |= 0xFFFFFFFFFFFFFFFF >> currentBitCount; + destination[dstOffset++] = (byte)(currentBits >> 56); + } + + return dstOffset; + } + + [Fact] + public void HuffmanDecoding_ValidEncoding_Succeeds() + { + foreach (byte[] input in TestData()) + { + // Worst case encoding is 30 bits per input byte, so make the encoded buffer 4 times as big + byte[] encoded = new byte[input.Length * 4]; + int encodedByteCount = Encode(input, encoded, false); + + // Worst case decoding is an output byte per 5 input bits, so make the decoded buffer 2 times as big + byte[] decoded = new byte[encoded.Length * 2]; + + int decodedByteCount = Huffman.Decode(new ReadOnlySpan<byte>(encoded, 0, encodedByteCount), ref decoded); + + Assert.Equal(input.Length, decodedByteCount); + Assert.Equal(input, decoded.Take(decodedByteCount)); + } + } + + [Fact] + public void HuffmanDecoding_InvalidEncoding_Throws() + { + foreach (byte[] encoded in InvalidEncodingData()) + { + // Worst case decoding is an output byte per 5 input bits, so make the decoded buffer 2 times as big + byte[] decoded = new byte[encoded.Length * 2]; + + Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(encoded, ref decoded)); + } + } + + // This input sequence will encode to 17 bits, thus offsetting the next character to encode + // by exactly one bit. We use this below to generate a prefix that encodes all of the possible starting + // bit offsets for a character, from 0 to 7. + private static readonly byte[] s_offsetByOneBit = new byte[] { (byte)'c', (byte)'l', (byte)'r' }; + + public static IEnumerable<byte[]> TestData() + { + // Single byte data + for (int i = 0; i < 256; i++) + { + yield return new byte[] { (byte)i }; + } + + // Ensure that decoding every possible value leaves the decoder in a correct state so that + // a subsequent value can be decoded (here, 'a') + for (int i = 0; i < 256; i++) + { + yield return new byte[] { (byte)i, (byte)'a' }; + } + + // Ensure that every possible bit starting position for every value is encoded properly + // s_offsetByOneBit encodes to exactly 17 bits, leaving 1 bit for the next byte + // So by repeating this sequence, we can generate any starting bit position we want. + byte[] currentPrefix = new byte[0]; + for (int prefixBits = 1; prefixBits <= 8; prefixBits++) + { + currentPrefix = currentPrefix.Concat(s_offsetByOneBit).ToArray(); + + // Make sure we're actually getting the correct number of prefix bits + int encodedBits = currentPrefix.Select(b => Huffman.Encode(b).bitLength).Sum(); + Assert.Equal(prefixBits % 8, encodedBits % 8); + + for (int i = 0; i < 256; i++) + { + yield return currentPrefix.Concat(new byte[] { (byte)i }.Concat(currentPrefix)).ToArray(); + } + } + + // Finally, one really big chunk of randomly generated data. + byte[] data = new byte[1024 * 1024]; + new Random(42).NextBytes(data); + yield return data; + } + + private static IEnumerable<byte[]> InvalidEncodingData() + { + // For encodings greater than 8 bits, truncate one or more bytes to generate an invalid encoding + byte[] source = new byte[1]; + byte[] destination = new byte[10]; + for (int i = 0; i < 256; i++) + { + source[0] = (byte)i; + int encodedByteCount = Encode(source, destination, false); + if (encodedByteCount > 1) + { + yield return destination.Take(encodedByteCount - 1).ToArray(); + if (encodedByteCount > 2) + { + yield return destination.Take(encodedByteCount - 2).ToArray(); + if (encodedByteCount > 3) + { + yield return destination.Take(encodedByteCount - 3).ToArray(); + } + } + } + } + + // Pad encodings with invalid trailing one bits. This is disallowed. + byte[] pad1 = new byte[] { 0xFF }; + byte[] pad2 = new byte[] { 0xFF, 0xFF, }; + byte[] pad3 = new byte[] { 0xFF, 0xFF, 0xFF }; + byte[] pad4 = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }; + + for (int i = 0; i < 256; i++) + { + source[0] = (byte)i; + int encodedByteCount = Encode(source, destination, false); + yield return destination.Take(encodedByteCount).Concat(pad1).ToArray(); + yield return destination.Take(encodedByteCount).Concat(pad2).ToArray(); + yield return destination.Take(encodedByteCount).Concat(pad3).ToArray(); + yield return destination.Take(encodedByteCount).Concat(pad4).ToArray(); + } + + // send single EOS + yield return new byte[] { 0b11111111, 0b11111111, 0b11111111, 0b11111100 }; + + // send combinations with EOS in the middle + source = new byte[2]; + destination = new byte[24]; + for (int i = 0; i < 256; i++) + { + source[0] = source[1] = (byte)i; + int encodedByteCount = Encode(source, destination, true); + yield return destination.Take(encodedByteCount).ToArray(); + } + } + public static readonly TheoryData<byte[], byte[]> _validData = new TheoryData<byte[], byte[]> { // Single 5-bit symbol @@ -67,8 +245,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(_validData))] public void HuffmanDecodeArray(byte[] encoded, byte[] expected) { - var dst = new byte[expected.Length]; - Assert.Equal(expected.Length, Huffman.Decode(new ReadOnlySpan<byte>(encoded), dst)); + byte[] dst = new byte[expected.Length]; + Assert.Equal(expected.Length, Huffman.Decode(new ReadOnlySpan<byte>(encoded), ref dst)); Assert.Equal(expected, dst); } @@ -88,8 +266,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(_longPaddingData))] public void ThrowsOnPaddingLongerThanSevenBits(byte[] encoded) { - var exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), new byte[encoded.Length * 2])); - Assert.Equal(CoreStrings.HPackHuffmanErrorIncomplete, exception.Message); + byte[] dst = new byte[encoded.Length * 2]; + Exception exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), ref dst)); + Assert.Equal(SR.net_http_hpack_huffman_decode_failed, exception.Message); } public static readonly TheoryData<byte[]> _eosData = new TheoryData<byte[]> @@ -104,17 +283,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(_eosData))] public void ThrowsOnEOS(byte[] encoded) { - var exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), new byte[encoded.Length * 2])); - Assert.Equal(CoreStrings.HPackHuffmanErrorEOS, exception.Message); + byte[] dst = new byte[encoded.Length * 2]; + Exception exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), ref dst)); + Assert.Equal(SR.net_http_hpack_huffman_decode_failed, exception.Message); } [Fact] - public void ThrowsOnDestinationBufferTooSmall() + public void ResizesOnDestinationBufferTooSmall() { // h e l l o * - var encoded = new byte[] { 0b100111_00, 0b101_10100, 0b0_101000_0, 0b0111_1111 }; - var exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), new byte[encoded.Length])); - Assert.Equal(CoreStrings.HPackHuffmanErrorDestinationTooSmall, exception.Message); + byte[] encoded = new byte[] { 0b100111_00, 0b101_10100, 0b0_101000_0, 0b0111_1111 }; + byte[] originalDestination = new byte[encoded.Length]; + byte[] actualDestination = originalDestination; + int decodedCount = Huffman.Decode(new ReadOnlySpan<byte>(encoded), ref actualDestination); + Assert.Equal(5, decodedCount); + Assert.NotSame(originalDestination, actualDestination); } public static readonly TheoryData<byte[]> _incompleteSymbolData = new TheoryData<byte[]> @@ -145,28 +328,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(_incompleteSymbolData))] public void ThrowsOnIncompleteSymbol(byte[] encoded) { - var exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), new byte[encoded.Length * 2])); - Assert.Equal(CoreStrings.HPackHuffmanErrorIncomplete, exception.Message); + byte[] dst = new byte[encoded.Length * 2]; + Exception exception = Assert.Throws<HuffmanDecodingException>(() => Huffman.Decode(new ReadOnlySpan<byte>(encoded), ref dst)); + Assert.Equal(SR.net_http_hpack_huffman_decode_failed, exception.Message); } [Fact] public void DecodeCharactersThatSpans5Octets() { - var expectedLength = 2; - var decodedBytes = new byte[expectedLength]; + int expectedLength = 2; + byte[] decodedBytes = new byte[expectedLength]; // B LF EOS - var encoded = new byte[] { 0b1011101_1, 0b11111111, 0b11111111, 0b11111111, 0b11100_111 }; - var decodedLength = Huffman.Decode(new ReadOnlySpan<byte>(encoded, 0, encoded.Length), decodedBytes); + byte[] encoded = new byte[] { 0b1011101_1, 0b11111111, 0b11111111, 0b11111111, 0b11100_111 }; + int decodedLength = Huffman.Decode(new ReadOnlySpan<byte>(encoded, 0, encoded.Length), ref decodedBytes); Assert.Equal(expectedLength, decodedLength); - Assert.Equal(new byte [] { (byte)'B', (byte)'\n' }, decodedBytes); + Assert.Equal(new byte[] { (byte)'B', (byte)'\n' }, decodedBytes); } [Theory] [MemberData(nameof(HuffmanData))] public void HuffmanEncode(int code, uint expectedEncoded, int expectedBitLength) { - var (encoded, bitLength) = Huffman.Encode(code); + (uint encoded, int bitLength) = Huffman.Encode(code); Assert.Equal(expectedEncoded, encoded); Assert.Equal(expectedBitLength, bitLength); } @@ -175,7 +359,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(HuffmanData))] public void HuffmanDecode(int code, uint encoded, int bitLength) { - Assert.Equal(code, Huffman.DecodeValue(encoded, bitLength, out var decodedBits)); + Assert.Equal(code, Huffman.DecodeValue(encoded, bitLength, out int decodedBits)); Assert.Equal(bitLength, decodedBits); } @@ -183,14 +367,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests [MemberData(nameof(HuffmanData))] public void HuffmanEncodeDecode( int code, -// Suppresses the warning about an unused theory parameter because -// this test shares data with other methods + // Suppresses the warning about an unused theory parameter because + // this test shares data with other methods #pragma warning disable xUnit1026 uint encoded, #pragma warning restore xUnit1026 int bitLength) { - Assert.Equal(code, Huffman.DecodeValue(Huffman.Encode(code).encoded, bitLength, out var decodedBits)); + Assert.Equal(code, Huffman.DecodeValue(Huffman.Encode(code).encoded, bitLength, out int decodedBits)); Assert.Equal(bitLength, decodedBits); } @@ -198,7 +382,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests { get { - var data = new TheoryData<int, uint, int>(); + TheoryData<int, uint, int> data = new TheoryData<int, uint, int>(); data.Add(0, 0b11111111_11000000_00000000_00000000, 13); data.Add(1, 0b11111111_11111111_10110000_00000000, 23); diff --git a/src/Shared/test/Shared.Tests/Http2/ReadMe.SharedCode.md b/src/Shared/test/Shared.Tests/Http2/ReadMe.SharedCode.md new file mode 100644 index 0000000000..8cb8d8d2ab --- /dev/null +++ b/src/Shared/test/Shared.Tests/Http2/ReadMe.SharedCode.md @@ -0,0 +1,5 @@ +The code in this directory is shared between the runtime libraries and AspNetCore. This contains tests for HTTP/2 protocol infrastructure such as HPACK. Any changes to this dir need to be checked into both repositories. + +For additional details see: +- runtime/src/libraries/Common/src/System/Net/Http/Http2/ReadMe.SharedCode.md +- AspNetCore/src/Shared/Http2/ReadMe.SharedCode.md diff --git a/src/Shared/test/Shared.Tests/HttpSysGetHttpProtocolVersionTest.cs b/src/Shared/test/Shared.Tests/HttpSysGetHttpProtocolVersionTest.cs new file mode 100644 index 0000000000..d100660ba2 --- /dev/null +++ b/src/Shared/test/Shared.Tests/HttpSysGetHttpProtocolVersionTest.cs @@ -0,0 +1,29 @@ +// 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 Xunit; + +namespace Microsoft.AspNetCore.HttpSys.Internal +{ + public class HttpSysGetHttpProtocolVersionTest + { + public static TheoryData<Version, string> s_data = new TheoryData<Version, string> + { + { new Version(2, 0), "HTTP/2" }, + { new Version(1, 1), "HTTP/1.1" }, + { new Version(1, 0), "HTTP/1.0" }, + { new Version(0, 3), "HTTP/0.3" }, + { new Version(2, 1), "HTTP/2.1" } + }; + + [Theory] + [MemberData(nameof(s_data))] + public void GetHttpProtocolVersion_CorrectIETFVersion(Version version, string expected) + { + var actual = version.GetHttpProtocolVersion(); + + Assert.Equal(expected, actual); + } + } +} diff --git a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj index 83fe4babb7..76dfe2c60f 100644 --- a/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj +++ b/src/Shared/test/Shared.Tests/Microsoft.AspNetCore.Shared.Tests.csproj @@ -4,18 +4,20 @@ <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks> <DebugType>portable</DebugType> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <NoWarn>CS0649</NoWarn><!-- Not all APIs are called in the shared test project --> </PropertyGroup> <ItemGroup> - <Compile Include="$(SharedSourceRoot)ClosedGenericMatcher\*.cs" /> - <Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" /> - <Compile Include="$(SharedSourceRoot)HttpSys\**\*.cs" /> - <Compile Include="$(SharedSourceRoot)ObjectMethodExecutor\*.cs" /> - <Compile Include="$(SharedSourceRoot)PropertyActivator\*.cs" /> - <Compile Include="$(SharedSourceRoot)PropertyHelper\*.cs" /> - <Compile Include="$(SharedSourceRoot)SecurityHelper\**\*.cs" /> - <Compile Include="$(SharedSourceRoot)StackTrace\StackFrame\**\*.cs" /> - <Compile Include="$(SharedSourceRoot)WebEncoders\**\*.cs" /> + <Compile Include="$(SharedSourceRoot)ClosedGenericMatcher\*.cs" Link="Shared\ClosedGenericMatcher\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)CopyOnWriteDictionary\*.cs" Link="Shared\CopyOnWriteDictionary\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)Http2\**\*.cs" Link="Shared\Http2\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)HttpSys\**\*.cs" Link="Shared\HttpSys\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)ObjectMethodExecutor\*.cs" Link="Shared\ObjectMethodExecutor\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)PropertyActivator\*.cs" Link="Shared\PropertyActivator\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)PropertyHelper\*.cs" Link="Shared\PropertyHelper\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)SecurityHelper\**\*.cs" Link="Shared\SecurityHelper\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)StackTrace\StackFrame\**\*.cs" Link="Shared\StackTrace\%(Filename)%(Extension)"/> + <Compile Include="$(SharedSourceRoot)WebEncoders\**\*.cs" Link="Shared\WebEncoders\%(Filename)%(Extension)"/> </ItemGroup> <ItemGroup> @@ -30,6 +32,10 @@ <ItemGroup> <ProjectReference Include="..\testassets\ThrowingLibrary\ThrowingLibrary.csproj" /> + <EmbeddedResource Include="$(SharedSourceRoot)Http2\SR.resx" Link="Shared\Http2\SR.resx"> + <ManifestResourceName>System.Net.Http.SR</ManifestResourceName> + <Generator></Generator> + </EmbeddedResource> </ItemGroup> </Project> diff --git a/src/Shared/test/Shared.Tests/PropertyActivatorTest.cs b/src/Shared/test/Shared.Tests/PropertyActivatorTest.cs index a5cb1605b3..8775d692ca 100644 --- a/src/Shared/test/Shared.Tests/PropertyActivatorTest.cs +++ b/src/Shared/test/Shared.Tests/PropertyActivatorTest.cs @@ -153,7 +153,7 @@ namespace Microsoft.Extensions.Internal } [TestActivate] - public static int StaticActivatablProperty { get; set; } + public static int StaticActivatableProperty { get; set; } } private class TestClassWithPropertyVisiblity diff --git a/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs b/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs index 657a310b6e..b6a2d0c2bf 100644 --- a/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs +++ b/src/Shared/test/Shared.Tests/StackTraceHelperTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -33,7 +33,7 @@ namespace Microsoft.Extensions.Internal } // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert Assert.Collection(stackFrames, @@ -55,7 +55,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => GenericMethod<string>(null)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -69,7 +69,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => MethodWithOutParameter(out var value)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -83,7 +83,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => MethodWithGenericOutParameter("Test", out int value)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -98,7 +98,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => MethodWithRefParameter(ref value)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -113,7 +113,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => MethodWithGenericRefParameter(ref value)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -128,7 +128,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => MethodWithNullableParameter(value)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -142,7 +142,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => new GenericClass<int>().Throw(0)); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -175,7 +175,7 @@ namespace Microsoft.Extensions.Internal } // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); var methodNames = stackFrames.Select(stackFrame => stackFrame.MethodDisplayInfo.ToString()).ToArray(); // Assert @@ -189,7 +189,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => InvokeMethodOnTypeWithStackTraceHiddenAttribute()); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -204,7 +204,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => InvokeStaticMethodOnTypeWithStackTraceHiddenAttribute()); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -219,7 +219,7 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(() => new TypeWithMethodWithStackTraceHiddenAttribute().Throw()); // Act - var stackFrames = StackTraceHelper.GetFrames(exception); + var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); @@ -237,12 +237,14 @@ namespace Microsoft.Extensions.Internal var exception = Record.Exception(action); // Act - var frames = StackTraceHelper.GetFrames(exception).ToArray(); + var frames = StackTraceHelper.GetFrames(exception, out _).ToArray(); // Assert var frame = frames[0]; Assert.Null(frame.FilePath); - Assert.Equal($"lambda_method(Closure )", frame.MethodDisplayInfo.ToString()); + // lambda_method{RandomNumber}(Closure ) + Assert.StartsWith("lambda_method", frame.MethodDisplayInfo.ToString()); + Assert.EndsWith("(Closure )", frame.MethodDisplayInfo.ToString()); } [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)] diff --git a/src/SignalR/README.md b/src/SignalR/README.md index 084b5fbf71..ac3d241c04 100644 --- a/src/SignalR/README.md +++ b/src/SignalR/README.md @@ -1,13 +1,13 @@ ASP.NET Core SignalR ==================== -ASP.NET Core SignalR is a new library for ASP.NET Core developers that makes it incredibly simple to add real-time web functionality to your applications. What is "real-time web" functionality? It's the ability to have your server-side code push content to the connected clients as it happens, in real-time. +ASP.NET Core SignalR is a library for ASP.NET Core developers that makes it incredibly simple to add real-time web functionality to your applications. What is "real-time web" functionality? It's the ability to have your server-side code push content to the connected clients as it happens, in real-time. You can watch an introductory presentation here - [ASP.NET Core SignalR: Build 2018](https://www.youtube.com/watch?v=Lws0zOaseIM) ## Documentation -Documentation for ASP.NET Core SignalR can be found in the [Real-time Apps](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-2.1) section of the ASP.NET Core Documentation site. +Documentation for ASP.NET Core SignalR can be found in the [Real-time Apps](https://docs.microsoft.com/aspnet/core/signalr/introduction) section of the ASP.NET Core Documentation site. ## TypeScript Version @@ -20,33 +20,33 @@ When in doubt, check the version of TypeScript referenced by our [package.json]( You can install the latest released JavaScript client from npm with the following command: ```bash -npm install @aspnet/signalr +npm install @microsoft/signalr ``` -The `@aspnet/signalr` package (and it's dependencies) require NPM 5.6.0 or higher. +The `@microsoft/signalr` package (and it's dependencies) require NPM 5.6.0 or higher. -**NOTE:** Previous previews of the SignalR client library for JavaScript were named `@aspnet/signalr-client`. This has been deprecated as of Preview 1. +**NOTE:** Previous versions of the SignalR client were named `@aspnet/signalr` or `@aspnet/signalr-client`. **IMPORTANT:** When using preview builds, you should always ensure you are using the same version of both the JavaScript client and the Server. The version numbers should align as they are produced in the same build process. -The CI build publishes the latest dev version of the JavaScript client to our dev npm registry as @aspnet/signalr. You can install the module as follows: +The CI build publishes the latest dev version of the JavaScript client to our dev npm registry as @microsoft/signalr. You can install the module as follows: - Create an .npmrc file with the following line: - `@aspnet:registry=https://dotnet.myget.org/f/aspnetcore-dev/npm/` + `@microsoft:registry=https://dotnet.myget.org/f/aspnetcore-dev/npm/` - Run: - `npm install @aspnet/signalr` + `npm install @microsoft/signalr` Alternatively, if you don't want to create the .npmrc file run the following commands: ``` -npm install @aspnet/signalr --registry https://dotnet.myget.org/f/aspnetcore-dev/npm/ +npm install @microsoft/signalr --registry https://dotnet.myget.org/f/aspnetcore-dev/npm/ ``` We also have a MsgPack protocol library which is installed via: ```bash -npm install @aspnet/signalr-protocol-msgpack +npm install @microsoft/signalr-protocol-msgpack ``` ## Deploying -Once you've installed the NPM modules, they will be located in the `node_modules/@aspnet/signalr` and `node_modules/@aspnet/signalr-protocol-msgpack` folders. If you are building a NodeJS application or using an ECMAScript module loader/bundler (such as [webpack](https://webpack.js.org)), you can load them directly. If you are building a browser application without using a module bundler, you can find UMD-compatible bundles in the `dist/browser` folder; minified versions are provided as well. Simply copy these to your project as appropriate and use a build task to keep them up-to-date. +Once you've installed the NPM modules, they will be located in the `node_modules/@microsoft/signalr` and `node_modules/@microsoft/signalr-protocol-msgpack` folders. If you are building a NodeJS application or using an ECMAScript module loader/bundler (such as [webpack](https://webpack.js.org)), you can load them directly. If you are building a browser application without using a module bundler, you can find UMD-compatible bundles in the `dist/browser` folder; minified versions are provided as well. Simply copy these to your project as appropriate and use a build task to keep them up-to-date. diff --git a/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs b/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs index a361a4ed03..5be77677a2 100644 --- a/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs +++ b/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.0.cs @@ -3,7 +3,7 @@ namespace Microsoft.AspNetCore.SignalR.Client { - public partial class HubConnection + public partial class HubConnection : System.IAsyncDisposable { public static readonly System.TimeSpan DefaultHandshakeTimeout; public static readonly System.TimeSpan DefaultKeepAliveInterval; @@ -11,15 +11,15 @@ namespace Microsoft.AspNetCore.SignalR.Client public HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.Net.EndPoint endPoint, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.Net.EndPoint endPoint, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy reconnectPolicy) { } public string ConnectionId { get { throw null; } } - public System.TimeSpan HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan ServerTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan ServerTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.SignalR.Client.HubConnectionState State { get { throw null; } } public event System.Func<System.Exception, System.Threading.Tasks.Task> Closed { add { } remove { } } public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } } public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } } [System.Diagnostics.DebuggerStepThroughAttribute] - public System.Threading.Tasks.Task DisposeAsync() { throw null; } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; } @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.SignalR.Client public partial class HubConnectionBuilder : Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder, Microsoft.AspNetCore.SignalR.ISignalRBuilder { public HubConnectionBuilder() { } - public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.SignalR.Client.HubConnection Build() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object obj) { throw null; } @@ -155,8 +155,8 @@ namespace Microsoft.AspNetCore.SignalR.Client public sealed partial class RetryContext { public RetryContext() { } - public System.TimeSpan ElapsedTime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long PreviousRetryCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Exception RetryReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan ElapsedTime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long PreviousRetryCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Exception RetryReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs b/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs index a361a4ed03..5be77677a2 100644 --- a/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs +++ b/src/SignalR/clients/csharp/Client.Core/ref/Microsoft.AspNetCore.SignalR.Client.Core.netstandard2.1.cs @@ -3,7 +3,7 @@ namespace Microsoft.AspNetCore.SignalR.Client { - public partial class HubConnection + public partial class HubConnection : System.IAsyncDisposable { public static readonly System.TimeSpan DefaultHandshakeTimeout; public static readonly System.TimeSpan DefaultKeepAliveInterval; @@ -11,15 +11,15 @@ namespace Microsoft.AspNetCore.SignalR.Client public HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.Net.EndPoint endPoint, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public HubConnection(Microsoft.AspNetCore.Connections.IConnectionFactory connectionFactory, Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol, System.Net.EndPoint endPoint, System.IServiceProvider serviceProvider, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, Microsoft.AspNetCore.SignalR.Client.IRetryPolicy reconnectPolicy) { } public string ConnectionId { get { throw null; } } - public System.TimeSpan HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan ServerTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan ServerTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.SignalR.Client.HubConnectionState State { get { throw null; } } public event System.Func<System.Exception, System.Threading.Tasks.Task> Closed { add { } remove { } } public event System.Func<string, System.Threading.Tasks.Task> Reconnected { add { } remove { } } public event System.Func<System.Exception, System.Threading.Tasks.Task> Reconnecting { add { } remove { } } [System.Diagnostics.DebuggerStepThroughAttribute] - public System.Threading.Tasks.Task DisposeAsync() { throw null; } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } [System.Diagnostics.DebuggerStepThroughAttribute] public System.Threading.Tasks.Task<object> InvokeCoreAsync(string methodName, System.Type returnType, object[] args, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public System.IDisposable On(string methodName, System.Type[] parameterTypes, System.Func<object[], object, System.Threading.Tasks.Task> handler, object state) { throw null; } @@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.SignalR.Client public partial class HubConnectionBuilder : Microsoft.AspNetCore.SignalR.Client.IHubConnectionBuilder, Microsoft.AspNetCore.SignalR.ISignalRBuilder { public HubConnectionBuilder() { } - public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.SignalR.Client.HubConnection Build() { throw null; } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public override bool Equals(object obj) { throw null; } @@ -155,8 +155,8 @@ namespace Microsoft.AspNetCore.SignalR.Client public sealed partial class RetryContext { public RetryContext() { } - public System.TimeSpan ElapsedTime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long PreviousRetryCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Exception RetryReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan ElapsedTime { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long PreviousRetryCount { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Exception RetryReason { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs b/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs index caf9a4b514..051faade87 100644 --- a/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs +++ b/src/SignalR/clients/csharp/Client.Core/src/HubConnection.cs @@ -22,7 +22,6 @@ using Microsoft.AspNetCore.SignalR.Internal; using Microsoft.AspNetCore.SignalR.Protocol; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.SignalR.Client { @@ -34,7 +33,7 @@ namespace Microsoft.AspNetCore.SignalR.Client /// Before hub methods can be invoked the connection must be started using <see cref="StartAsync"/>. /// Clean up a connection using <see cref="StopAsync"/> or <see cref="DisposeAsync"/>. /// </remarks> - public partial class HubConnection + public partial class HubConnection : IAsyncDisposable { public static readonly TimeSpan DefaultServerTimeout = TimeSpan.FromSeconds(30); // Server ping rate is 15 sec, this is 2 times that. public static readonly TimeSpan DefaultHandshakeTimeout = TimeSpan.FromSeconds(15); @@ -292,8 +291,8 @@ namespace Microsoft.AspNetCore.SignalR.Client /// <summary> /// Disposes the <see cref="HubConnection"/>. /// </summary> - /// <returns>A <see cref="Task"/> that represents the asynchronous dispose.</returns> - public async Task DisposeAsync() + /// <returns>A <see cref="ValueTask"/> that represents the asynchronous dispose.</returns> + public async ValueTask DisposeAsync() { if (!_disposed) { @@ -504,8 +503,16 @@ namespace Microsoft.AspNetCore.SignalR.Client if (disposing) { - (_serviceProvider as IDisposable)?.Dispose(); + // Must set this before calling DisposeAsync because the service provider has a reference to the HubConnection and will try to dispose it again _disposed = true; + if (_serviceProvider is IAsyncDisposable asyncDispose) + { + await asyncDispose.DisposeAsync(); + } + else + { + (_serviceProvider as IDisposable)?.Dispose(); + } } } finally @@ -532,7 +539,7 @@ namespace Microsoft.AspNetCore.SignalR.Client /// </returns> public IAsyncEnumerable<TResult> StreamAsyncCore<TResult>(string methodName, object[] args, CancellationToken cancellationToken = default) { - var cts = cancellationToken.CanBeCanceled ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) : new CancellationTokenSource(); + var cts = cancellationToken.CanBeCanceled ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, default) : new CancellationTokenSource(); var stream = CastIAsyncEnumerable<TResult>(methodName, args, cts); var cancelableStream = AsyncEnumerableAdapters.MakeCancelableTypedAsyncEnumerable(stream, cts); return cancelableStream; @@ -1626,6 +1633,7 @@ namespace Microsoft.AspNetCore.SignalR.Client { private readonly HubConnection _hubConnection; private readonly ILogger _logger; + private readonly bool _hasInherentKeepAlive; private readonly object _lock = new object(); private readonly Dictionary<string, InvocationRequest> _pendingCalls = new Dictionary<string, InvocationRequest>(StringComparer.Ordinal); @@ -1637,7 +1645,6 @@ namespace Microsoft.AspNetCore.SignalR.Client private long _nextActivationServerTimeout; private long _nextActivationSendPing; - private bool _hasInherentKeepAlive; public ConnectionContext Connection { get; } public Task ReceiveTask { get; set; } @@ -1766,7 +1773,10 @@ namespace Microsoft.AspNetCore.SignalR.Client // Old clients never ping, and shouldn't be timed out, so ping to tell the server that we should be timed out if we stop. // The TimerLoop is started from the ReceiveLoop with the connection lock still acquired. _hubConnection._state.AssertInConnectionLock(); - await _hubConnection.SendHubMessage(this, PingMessage.Instance); + if (!_hasInherentKeepAlive) + { + await _hubConnection.SendHubMessage(this, PingMessage.Instance); + } // initialize the timers timer.Start(); @@ -1796,7 +1806,12 @@ namespace Microsoft.AspNetCore.SignalR.Client // Internal for testing internal async Task RunTimerActions() { - if (!_hasInherentKeepAlive && DateTime.UtcNow.Ticks > Volatile.Read(ref _nextActivationServerTimeout)) + if (_hasInherentKeepAlive) + { + return; + } + + if (DateTime.UtcNow.Ticks > Volatile.Read(ref _nextActivationServerTimeout)) { OnServerTimeout(); } diff --git a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj index df54c48fec..e287d4c869 100644 --- a/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj +++ b/src/SignalR/clients/csharp/Client.Core/src/Microsoft.AspNetCore.SignalR.Client.Core.csproj @@ -32,7 +32,7 @@ <Reference Include="Microsoft.Bcl.AsyncInterfaces" /> </ItemGroup> - <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '3.1'"> + <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '5.0'"> <!-- This dependency was replaced by Protocols.NewtonsoftJson between 3.0 and 2.2. This suppression can be removed after 3.0 is complete. --> <SuppressBaselineReference Include="Microsoft.AspNetCore.SignalR.Protocols.Json" /> </ItemGroup> diff --git a/src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs b/src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs index 6dbd4e032e..5d40dcaf70 100644 --- a/src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs +++ b/src/SignalR/clients/csharp/Client/test/FunctionalTests/HubConnectionTests.cs @@ -1479,6 +1479,118 @@ namespace Microsoft.AspNetCore.SignalR.Client.FunctionalTests } } + [Fact] + public async Task UserAgentIsSet() + { + using (StartServer<Startup>(out var server)) + { + var hubConnection = new HubConnectionBuilder() + .WithLoggerFactory(LoggerFactory) + .WithUrl(server.Url + "/default", HttpTransportType.LongPolling, options => + { + options.Headers["X-test"] = "42"; + options.Headers["X-42"] = "test"; + }) + .Build(); + try + { + await hubConnection.StartAsync().OrTimeout(); + var headerValues = await hubConnection.InvokeAsync<string[]>(nameof(TestHub.GetHeaderValues), new[] { "User-Agent" }).OrTimeout(); + Assert.NotNull(headerValues); + Assert.Single(headerValues); + + var userAgent = headerValues[0]; + + Assert.StartsWith("Microsoft SignalR/", userAgent); + + var majorVersion = typeof(HttpConnection).Assembly.GetName().Version.Major; + var minorVersion = typeof(HttpConnection).Assembly.GetName().Version.Minor; + + Assert.Contains($"{majorVersion}.{minorVersion}", userAgent); + + } + catch (Exception ex) + { + LoggerFactory.CreateLogger<HubConnectionTests>().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName); + throw; + } + finally + { + await hubConnection.DisposeAsync().OrTimeout(); + } + } + } + + [Fact] + public async Task UserAgentCanBeCleared() + { + using (StartServer<Startup>(out var server)) + { + var hubConnection = new HubConnectionBuilder() + .WithLoggerFactory(LoggerFactory) + .WithUrl(server.Url + "/default", HttpTransportType.LongPolling, options => + { + options.Headers["User-Agent"] = ""; + }) + .Build(); + try + { + await hubConnection.StartAsync().OrTimeout(); + var headerValues = await hubConnection.InvokeAsync<string[]>(nameof(TestHub.GetHeaderValues), new[] { "User-Agent" }).OrTimeout(); + Assert.NotNull(headerValues); + Assert.Single(headerValues); + + var userAgent = headerValues[0]; + + Assert.Null(userAgent); + } + catch (Exception ex) + { + LoggerFactory.CreateLogger<HubConnectionTests>().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName); + throw; + } + finally + { + await hubConnection.DisposeAsync().OrTimeout(); + } + } + } + + [Fact] + public async Task UserAgentCanBeSet() + { + using (StartServer<Startup>(out var server)) + { + var hubConnection = new HubConnectionBuilder() + .WithLoggerFactory(LoggerFactory) + .WithUrl(server.Url + "/default", HttpTransportType.LongPolling, options => + { + options.Headers["User-Agent"] = "User Value"; + }) + .Build(); + try + { + await hubConnection.StartAsync().OrTimeout(); + var headerValues = await hubConnection.InvokeAsync<string[]>(nameof(TestHub.GetHeaderValues), new[] { "User-Agent" }).OrTimeout(); + Assert.NotNull(headerValues); + Assert.Single(headerValues); + + var userAgent = headerValues[0]; + + Assert.Equal("User Value", userAgent); + } + catch (Exception ex) + { + LoggerFactory.CreateLogger<HubConnectionTests>().LogError(ex, "{ExceptionType} from test", ex.GetType().FullName); + throw; + } + finally + { + await hubConnection.DisposeAsync().OrTimeout(); + } + } + } + [ConditionalFact] [WebSocketsSupportedCondition] public async Task WebSocketOptionsAreApplied() diff --git a/src/SignalR/clients/csharp/Client/test/UnitTests/HttpConnectionTests.Transport.cs b/src/SignalR/clients/csharp/Client/test/UnitTests/HttpConnectionTests.Transport.cs index 142e40546c..0244af0afd 100644 --- a/src/SignalR/clients/csharp/Client/test/UnitTests/HttpConnectionTests.Transport.cs +++ b/src/SignalR/clients/csharp/Client/test/UnitTests/HttpConnectionTests.Transport.cs @@ -3,6 +3,7 @@ using System; using System.IO.Pipelines; +using System.Linq; using System.Net; using System.Net.Http; using System.Reflection; @@ -113,16 +114,17 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests testHttpHandler.OnRequest(async (request, next, token) => { - var userAgentHeaderCollection = request.Headers.UserAgent; - var userAgentHeader = Assert.Single(userAgentHeaderCollection); - Assert.Equal("Microsoft.AspNetCore.Http.Connections.Client", userAgentHeader.Product.Name); + var userAgentHeader = request.Headers.UserAgent.ToString(); + + Assert.NotNull(userAgentHeader); + Assert.StartsWith("Microsoft SignalR/", userAgentHeader); // user agent version should come from version embedded in assembly metadata var assemblyVersion = typeof(Constants) .Assembly .GetCustomAttribute<AssemblyInformationalVersionAttribute>(); - Assert.Equal(assemblyVersion.InformationalVersion, userAgentHeader.Product.Version); + Assert.Contains(assemblyVersion.InformationalVersion, userAgentHeader); requestsExecuted = true; diff --git a/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.Protocol.cs b/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.Protocol.cs index 93cc3dd863..e254a79c5c 100644 --- a/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.Protocol.cs +++ b/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.Protocol.cs @@ -648,6 +648,33 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests await connection.DisposeAsync().OrTimeout(); } } + + [Fact] + public async Task ClientWithInherentKeepAliveDoesNotPing() + { + var connection = new TestConnection(hasInherentKeepAlive: true); + var hubConnection = CreateHubConnection(connection); + + hubConnection.TickRate = TimeSpan.FromMilliseconds(30); + hubConnection.KeepAliveInterval = TimeSpan.FromMilliseconds(80); + + try + { + await hubConnection.StartAsync().OrTimeout(); + + await Task.Delay(1000); + + await hubConnection.DisposeAsync().OrTimeout(); + await connection.DisposeAsync().OrTimeout(); + + Assert.Equal(0, (await connection.ReadAllSentMessagesAsync(ignorePings: false).OrTimeout()).Count); + } + finally + { + await hubConnection.DisposeAsync().OrTimeout(); + await connection.DisposeAsync().OrTimeout(); + } + } } } } diff --git a/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.cs b/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.cs index 2c9df93cb8..b303e71ddd 100644 --- a/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.cs +++ b/src/SignalR/clients/csharp/Client/test/UnitTests/HubConnectionTests.cs @@ -414,6 +414,17 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests } } + [Fact] + public async Task CanAwaitUsingHubConnection() + { + using (StartVerifiableLog()) + { + var connection = new TestConnection(); + await using var hubConnection = CreateHubConnection(connection, loggerFactory: LoggerFactory); + await hubConnection.StartAsync().OrTimeout(); + } + } + private class SampleObject { public SampleObject(string foo, int bar) diff --git a/src/SignalR/clients/csharp/Client/test/UnitTests/TestConnection.cs b/src/SignalR/clients/csharp/Client/test/UnitTests/TestConnection.cs index fbc516e95c..0da16cf160 100644 --- a/src/SignalR/clients/csharp/Client/test/UnitTests/TestConnection.cs +++ b/src/SignalR/clients/csharp/Client/test/UnitTests/TestConnection.cs @@ -10,6 +10,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Connections.Features; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.SignalR.Protocol; @@ -18,7 +19,7 @@ using Newtonsoft.Json.Linq; namespace Microsoft.AspNetCore.SignalR.Client.Tests { - internal class TestConnection : ConnectionContext + internal class TestConnection : ConnectionContext, IConnectionInherentKeepAliveFeature { private readonly bool _autoHandshake; private readonly TaskCompletionSource<object> _started = new TaskCompletionSource<object>(); @@ -30,6 +31,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests private readonly Func<Task> _onStart; private readonly Func<Task> _onDispose; + private readonly bool _hasInherentKeepAlive; public override string ConnectionId { get; set; } @@ -41,17 +43,22 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests public override IDictionary<object, object> Items { get; set; } = new ConnectionItems(); - public TestConnection(Func<Task> onStart = null, Func<Task> onDispose = null, bool autoHandshake = true) + bool IConnectionInherentKeepAliveFeature.HasInherentKeepAlive => _hasInherentKeepAlive; + + public TestConnection(Func<Task> onStart = null, Func<Task> onDispose = null, bool autoHandshake = true, bool hasInherentKeepAlive = false) { _autoHandshake = autoHandshake; _onStart = onStart ?? (() => Task.CompletedTask); _onDispose = onDispose ?? (() => Task.CompletedTask); + _hasInherentKeepAlive = hasInherentKeepAlive; var options = new PipeOptions(readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); Application = pair.Application; Transport = pair.Transport; + + Features.Set<IConnectionInherentKeepAliveFeature>(this); } public override ValueTask DisposeAsync() => DisposeCoreAsync(); @@ -119,6 +126,10 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests while (true) { var result = await ReadSentTextMessageAsyncInner(); + if (result == null) + { + return null; + } var receivedMessageType = (int?)JObject.Parse(result)["type"]; diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netcoreapp.cs b/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netcoreapp.cs new file mode 100644 index 0000000000..35b6c7cc35 --- /dev/null +++ b/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netcoreapp.cs @@ -0,0 +1,49 @@ +// 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. + +namespace Microsoft.AspNetCore.Http.Connections.Client +{ + public partial class HttpConnection : Microsoft.AspNetCore.Connections.ConnectionContext, Microsoft.AspNetCore.Connections.Features.IConnectionInherentKeepAliveFeature + { + public HttpConnection(Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionOptions httpConnectionOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } + public HttpConnection(System.Uri url) { } + public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) { } + public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } + public override string ConnectionId { get { throw null; } set { } } + public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + bool Microsoft.AspNetCore.Connections.Features.IConnectionInherentKeepAliveFeature.HasInherentKeepAlive { get { throw null; } } + public override System.IO.Pipelines.IDuplexPipe Transport { get { throw null; } set { } } + [System.Diagnostics.DebuggerStepThroughAttribute] + public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + [System.Diagnostics.DebuggerStepThroughAttribute] + public System.Threading.Tasks.Task StartAsync(Microsoft.AspNetCore.Connections.TransferFormat transferFormat, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.Task StartAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public partial class HttpConnectionOptions + { + public HttpConnectionOptions() { } + public System.Func<System.Threading.Tasks.Task<string>> AccessTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } set { } } + public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Net.CookieContainer Cookies { get { throw null; } set { } } + public System.Net.ICredentials Credentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } set { } } + public System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler> HttpMessageHandlerFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Net.IWebProxy Proxy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool SkipNegotiation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Uri Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public bool? UseDefaultCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Action<System.Net.WebSockets.ClientWebSocketOptions> WebSocketConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + } + public partial class NoTransportSupportedException : System.Exception + { + public NoTransportSupportedException(string message) { } + } + public partial class TransportFailedException : System.Exception + { + public TransportFailedException(string transportType, string message, System.Exception innerException = null) { } + public string TransportType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + } +} diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.0.cs b/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.0.cs index c83eff7848..c36c30930b 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.0.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.0.cs @@ -10,8 +10,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) { } public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public override string ConnectionId { get { throw null; } set { } } - public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } bool Microsoft.AspNetCore.Connections.Features.IConnectionInherentKeepAliveFeature.HasInherentKeepAlive { get { throw null; } } public override System.IO.Pipelines.IDuplexPipe Transport { get { throw null; } set { } } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -29,20 +29,20 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public partial class HttpConnectionOptions { public HttpConnectionOptions() { } - public System.Func<System.Threading.Tasks.Task<string>> AccessTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<System.Threading.Tasks.Task<string>> AccessTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } set { } } - public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Net.CookieContainer Cookies { get { throw null; } set { } } - public System.Net.ICredentials Credentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Connections.TransferFormat DefaultTransferFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Net.ICredentials Credentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Connections.TransferFormat DefaultTransferFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } set { } } - public System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler> HttpMessageHandlerFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.IWebProxy Proxy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SkipNegotiation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Uri Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? UseDefaultCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action<System.Net.WebSockets.ClientWebSocketOptions> WebSocketConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler> HttpMessageHandlerFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.IWebProxy Proxy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SkipNegotiation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Uri Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? UseDefaultCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action<System.Net.WebSockets.ClientWebSocketOptions> WebSocketConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class NoTransportSupportedException : System.Exception { @@ -51,6 +51,6 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public partial class TransportFailedException : System.Exception { public TransportFailedException(string transportType, string message, System.Exception innerException = null) { } - public string TransportType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string TransportType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs b/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs index c83eff7848..c36c30930b 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/ref/Microsoft.AspNetCore.Http.Connections.Client.netstandard2.1.cs @@ -10,8 +10,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports) { } public HttpConnection(System.Uri url, Microsoft.AspNetCore.Http.Connections.HttpTransportType transports, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } public override string ConnectionId { get { throw null; } set { } } - public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public override Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public override System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } bool Microsoft.AspNetCore.Connections.Features.IConnectionInherentKeepAliveFeature.HasInherentKeepAlive { get { throw null; } } public override System.IO.Pipelines.IDuplexPipe Transport { get { throw null; } set { } } [System.Diagnostics.DebuggerStepThroughAttribute] @@ -29,20 +29,20 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public partial class HttpConnectionOptions { public HttpConnectionOptions() { } - public System.Func<System.Threading.Tasks.Task<string>> AccessTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<System.Threading.Tasks.Task<string>> AccessTokenProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get { throw null; } set { } } - public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Net.CookieContainer Cookies { get { throw null; } set { } } - public System.Net.ICredentials Credentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Connections.TransferFormat DefaultTransferFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Net.ICredentials Credentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Connections.TransferFormat DefaultTransferFormat { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public System.Collections.Generic.IDictionary<string, string> Headers { get { throw null; } set { } } - public System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler> HttpMessageHandlerFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Net.IWebProxy Proxy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool SkipNegotiation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Uri Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? UseDefaultCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Action<System.Net.WebSockets.ClientWebSocketOptions> WebSocketConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Func<System.Net.Http.HttpMessageHandler, System.Net.Http.HttpMessageHandler> HttpMessageHandlerFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Net.IWebProxy Proxy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool SkipNegotiation { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Uri Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? UseDefaultCredentials { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Action<System.Net.WebSockets.ClientWebSocketOptions> WebSocketConfiguration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class NoTransportSupportedException : System.Exception { @@ -51,6 +51,6 @@ namespace Microsoft.AspNetCore.Http.Connections.Client public partial class TransportFailedException : System.Exception { public TransportFailedException(string transportType, string message, System.Exception innerException = null) { } - public string TransportType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string TransportType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } } diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs index 4375d11285..acfdce1010 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/HttpConnection.cs @@ -562,14 +562,34 @@ namespace Microsoft.AspNetCore.Http.Connections.Client httpClient.Timeout = HttpClientTimeout; // Start with the user agent header - httpClient.DefaultRequestHeaders.UserAgent.Add(Constants.UserAgentHeader); + httpClient.DefaultRequestHeaders.Add(Constants.UserAgent, Constants.UserAgentHeader); // Apply any headers configured on the HttpConnectionOptions if (_httpConnectionOptions?.Headers != null) { foreach (var header in _httpConnectionOptions.Headers) { - httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); + // Check if the key is User-Agent and remove if empty string then replace if it exists. + if (string.Equals(header.Key, Constants.UserAgent, StringComparison.OrdinalIgnoreCase)) + { + if (string.IsNullOrEmpty(header.Value)) + { + httpClient.DefaultRequestHeaders.Remove(header.Key); + } + else if (httpClient.DefaultRequestHeaders.Contains(header.Key)) + { + httpClient.DefaultRequestHeaders.Remove(header.Key); + httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); + } + else + { + httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); + } + } + else + { + httpClient.DefaultRequestHeaders.Add(header.Key, header.Value); + } } } diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Constants.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Constants.cs index 22b41d56f3..6b6809b837 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Constants.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/Constants.cs @@ -1,21 +1,21 @@ // 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.Diagnostics; using System.Linq; -using System.Net.Http.Headers; using System.Reflection; +using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Http.Connections.Client.Internal { internal static class Constants { - public static readonly ProductInfoHeaderValue UserAgentHeader; + public const string UserAgent = "User-Agent"; + public static readonly string UserAgentHeader; static Constants() { - var userAgent = "Microsoft.AspNetCore.Http.Connections.Client"; - var assemblyVersion = typeof(Constants) .Assembly .GetCustomAttributes<AssemblyInformationalVersionAttribute>() @@ -23,14 +23,68 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal Debug.Assert(assemblyVersion != null); - // assembly version attribute should always be present - // but in case it isn't then don't include version in user-agent - if (assemblyVersion != null) + var runtime = ".NET"; + var runtimeVersion = RuntimeInformation.FrameworkDescription; + + UserAgentHeader = ConstructUserAgent(typeof(Constants).Assembly.GetName().Version, assemblyVersion?.InformationalVersion, GetOS(), runtime, runtimeVersion); + } + + private static string GetOS() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - userAgent += "/" + assemblyVersion.InformationalVersion; + return "Windows NT"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return "macOS"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return "Linux"; + } + else + { + return ""; + } + } + + public static string ConstructUserAgent(Version version, string detailedVersion, string os, string runtime, string runtimeVersion) + { + var userAgent = $"Microsoft SignalR/{version.Major}.{version.Minor} ("; + + if (!string.IsNullOrEmpty(detailedVersion)) + { + userAgent += $"{detailedVersion}"; + } + else + { + userAgent += "Unknown Version"; } - UserAgentHeader = ProductInfoHeaderValue.Parse(userAgent); + if (!string.IsNullOrEmpty(os)) + { + userAgent += $"; {os}"; + } + else + { + userAgent += "; Unknown OS"; + } + + userAgent += $"; {runtime}"; + + if (!string.IsNullOrEmpty(runtimeVersion)) + { + userAgent += $"; {runtimeVersion}"; + } + else + { + userAgent += "; Unknown Runtime Version"; + } + + userAgent += ")"; + + return userAgent; } } } diff --git a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsMessageParser.cs b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsMessageParser.cs index 6d4b5b8ffb..ed4caa274a 100644 --- a/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsMessageParser.cs +++ b/src/SignalR/clients/csharp/Http.Connections.Client/src/Internal/ServerSentEventsMessageParser.cs @@ -15,8 +15,9 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal private const byte ByteLF = (byte)'\n'; private const byte ByteColon = (byte)':'; - private static ReadOnlySpan<byte> _dataPrefix => new byte[] { (byte)'d', (byte)'a', (byte)'t', (byte)'a', (byte)':', (byte)' ' }; - private static ReadOnlySpan<byte> _sseLineEnding => new byte[] { (byte)'\r', (byte)'\n' }; + // This uses C# compiler's ability to refer to static data directly. For more information see https://vcsjones.dev/2019/02/01/csharp-readonly-span-bytes-static + private static ReadOnlySpan<byte> DataPrefix => new byte[] { (byte)'d', (byte)'a', (byte)'t', (byte)'a', (byte)':', (byte)' ' }; + private static ReadOnlySpan<byte> SseLineEnding => new byte[] { (byte)'\r', (byte)'\n' }; private static readonly byte[] _newLine = Encoding.UTF8.GetBytes(Environment.NewLine); private InternalParseState _internalParserState = InternalParseState.ReadMessagePayload; @@ -74,7 +75,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal // data: foo\n\bar should be encoded as // data: foo\r\n // data: bar\r\n - else if (line[line.Length - _sseLineEnding.Length] != ByteCR) + else if (line[line.Length - SseLineEnding.Length] != ByteCR) { throw new FormatException("Unexpected '\\n' in message. A '\\n' character can only be used as part of the newline sequence '\\r\\n'"); } @@ -90,8 +91,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal EnsureStartsWithDataPrefix(line); // Slice away the 'data: ' - var payloadLength = line.Length - (_dataPrefix.Length + _sseLineEnding.Length); - var newData = line.Slice(_dataPrefix.Length, payloadLength).ToArray(); + var payloadLength = line.Length - (DataPrefix.Length + SseLineEnding.Length); + var newData = line.Slice(DataPrefix.Length, payloadLength).ToArray(); _data.Add(newData); start = lineEnd; @@ -162,7 +163,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal private void EnsureStartsWithDataPrefix(ReadOnlySpan<byte> line) { - if (!line.StartsWith(_dataPrefix)) + if (!line.StartsWith(DataPrefix)) { throw new FormatException("Expected the message prefix 'data: '"); } @@ -170,7 +171,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal private bool IsMessageEnd(ReadOnlySpan<byte> line) { - return line.Length == _sseLineEnding.Length && line.SequenceEqual(_sseLineEnding); + return line.Length == SseLineEnding.Length && line.SequenceEqual(SseLineEnding); } public enum ParseResult diff --git a/src/SignalR/clients/java/signalr/build.gradle b/src/SignalR/clients/java/signalr/build.gradle index 61b170a40d..4b18bba589 100644 --- a/src/SignalR/clients/java/signalr/build.gradle +++ b/src/SignalR/clients/java/signalr/build.gradle @@ -83,7 +83,7 @@ task generatePOM { project { inceptionYear '2018' description 'ASP.NET Core SignalR Client for Java applications' - url 'https://github.com/aspnet/AspNetCore' + url 'https://github.com/dotnet/aspnetcore' name groupId + ':' + artifactId licenses { license { @@ -93,9 +93,9 @@ task generatePOM { } } scm { - connection 'scm:git:git://github.com/aspnet/AspNetCore.git' - developerConnection 'scm:git:git://github.com/aspnet/AspNetCore.git' - url 'http://github.com/aspnet/AspNetCore/tree/master' + connection 'scm:git:git://github.com/dotnet/aspnetcore.git' + developerConnection 'scm:git:git://github.com/dotnet/aspnetcore.git' + url 'http://github.com/dotnet/aspnetcore/tree/master' } developers { developer { @@ -108,3 +108,27 @@ task generatePOM { } task createPackage(dependsOn: [jar,sourceJar,javadocJar,generatePOM]) + +task generateVersionClass { + inputs.property "version", project.version + outputs.dir "$buildDir/generated" + doFirst { + def versionFile = file("$buildDir/../src/main/java/com/microsoft/signalr/Version.java") + versionFile.parentFile.mkdirs() + versionFile.text = + """ +// 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. + +package com.microsoft.signalr; + +class Version { + public static String getDetailedVersion() { + return "$project.version"; + } +} +""" + } +} + +compileJava.dependsOn generateVersionClass diff --git a/src/SignalR/clients/java/signalr/signalr.client.java.javaproj b/src/SignalR/clients/java/signalr/signalr.client.java.javaproj index c6a61e3233..31ab061f2b 100644 --- a/src/SignalR/clients/java/signalr/signalr.client.java.javaproj +++ b/src/SignalR/clients/java/signalr/signalr.client.java.javaproj @@ -11,6 +11,8 @@ <IsShippingPackage>true</IsShippingPackage> + <IsTestProject>true</IsTestProject> + <!-- Disable gradle daemon on CI since the CI seems to try to wait for the daemon to shut down, which it doesn't do :) --> <GradleOptions Condition="'$(ContinuousIntegrationBuild)' == 'true'">$(GradleOptions) -Dorg.gradle.daemon=false</GradleOptions> </PropertyGroup> @@ -33,6 +35,9 @@ </PackDependsOn> </PropertyGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" /> + + <!-- Define Target overrides after importing Directory.Build.targets so these don't get overriden --> <Target Name="Pack" DependsOnTargets="$(PackDependsOn)" Condition="'$(IsPackable)' == 'true'"> <Message Text="> gradlew $(GradleOptions) createPackage" Importance="high" /> <Exec Command="./gradlew $(GradleOptions) createPackage" /> @@ -50,10 +55,8 @@ <Exec Command="./gradlew $(GradleOptions) test" IgnoreStandardErrorWarningFormat="true" /> </Target> - <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" /> - <PropertyGroup> <!-- Pass the Java Package Version down to Gradle --> - <GradleOptions>-PpackageVersion="$(PackageVersion)"</GradleOptions> + <GradleOptions Condition="'$(ContinuousIntegrationBuild)' == 'true'">$(GradleOptions) -PpackageVersion="$(PackageVersion)"</GradleOptions> </PropertyGroup> </Project> diff --git a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java index 36dca4f808..03390ab986 100644 --- a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java +++ b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java @@ -328,6 +328,7 @@ public class HubConnection { handshakeResponseSubject = CompletableSubject.create(); handshakeReceived = false; CompletableSubject tokenCompletable = CompletableSubject.create(); + localHeaders.put(UserAgentHelper.getUserAgentName(), UserAgentHelper.createUserAgentString()); if (headers != null) { this.localHeaders.putAll(headers); } diff --git a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/UserAgentHelper.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/UserAgentHelper.java new file mode 100644 index 0000000000..977797af5f --- /dev/null +++ b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/UserAgentHelper.java @@ -0,0 +1,81 @@ +// 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. + +package com.microsoft.signalr; + +public class UserAgentHelper { + + private final static String USER_AGENT = "User-Agent"; + + public static String getUserAgentName() { + return USER_AGENT; + } + + public static String createUserAgentString() { + return constructUserAgentString(Version.getDetailedVersion(), getOS(), "Java", getJavaVersion(), getJavaVendor()); + } + + public static String constructUserAgentString(String detailedVersion, String os, String runtime, String runtimeVersion, String vendor) { + StringBuilder agentBuilder = new StringBuilder("Microsoft SignalR/"); + + agentBuilder.append(getVersion(detailedVersion)); + agentBuilder.append(" ("); + agentBuilder.append(detailedVersion); + + agentBuilder.append("; "); + if (!os.isEmpty()) { + agentBuilder.append(os); + } else { + agentBuilder.append("Unknown OS"); + } + + agentBuilder.append("; "); + agentBuilder.append(runtime); + + agentBuilder.append("; "); + if (!runtimeVersion.isEmpty()) { + agentBuilder.append(runtimeVersion); + } else { + agentBuilder.append("Unknown Runtime Version"); + } + + agentBuilder.append("; "); + if (!vendor.isEmpty()) { + agentBuilder.append(vendor); + } else { + agentBuilder.append("Unknown Vendor"); + } + + agentBuilder.append(")"); + + return agentBuilder.toString(); + } + + static String getVersion(String detailedVersion) { + // Getting the index of the second . so we can return just the major and minor version. + int shortVersionIndex = detailedVersion.indexOf(".", detailedVersion.indexOf(".") + 1); + return detailedVersion.substring(0, shortVersionIndex); + } + + static String getJavaVendor() { + return System.getProperty("java.vendor"); + } + + static String getJavaVersion() { + return System.getProperty("java.version"); + } + + static String getOS() { + String osName = System.getProperty("os.name").toLowerCase(); + + if (osName.indexOf("win") >= 0) { + return "Windows NT"; + } else if (osName.contains("mac") || osName.contains("darwin")) { + return "macOS"; + } else if (osName.contains("linux")) { + return "Linux"; + } else { + return osName; + } + } +} diff --git a/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Version.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Version.java new file mode 100644 index 0000000000..4c73a498f6 --- /dev/null +++ b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Version.java @@ -0,0 +1,11 @@ + +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +package com.microsoft.signalr; + +class Version { + public static String getDetailedVersion() { + return "99.99.99-dev"; + } +} diff --git a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java index 3f1d7d5b3f..da28f279a4 100644 --- a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java +++ b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java @@ -1116,7 +1116,7 @@ class HubConnectionTest { hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); AtomicBoolean done = new AtomicBoolean(); - Single<String> result = hubConnection.invoke(String.class, "fixedMessage", null); + Single<String> result = hubConnection.invoke(String.class, "fixedMessage", (Object)null); result.doOnSuccess(value -> done.set(true)).subscribe(); assertEquals("{\"type\":1,\"invocationId\":\"1\",\"target\":\"fixedMessage\",\"arguments\":[null]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); assertFalse(done.get()); @@ -2266,6 +2266,77 @@ class HubConnectionTest { } } + @Test + public void userAgentHeaderIsSet() { + AtomicReference<String> header = new AtomicReference<>(); + TestHttpClient client = new TestHttpClient() + .on("POST", "http://example.com/negotiate?negotiateVersion=1", + (req) -> { + header.set(req.getHeaders().get("User-Agent")); + return Single.just(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\"" + + "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")); + }); + + MockTransport transport = new MockTransport(); + HubConnection hubConnection = HubConnectionBuilder.create("http://example.com") + .withTransportImplementation(transport) + .withHttpClient(client) + .build(); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); + hubConnection.stop(); + + assertTrue(header.get().startsWith("Microsoft SignalR/")); + } + + @Test + public void userAgentHeaderCanBeOverwritten() { + AtomicReference<String> header = new AtomicReference<>(); + TestHttpClient client = new TestHttpClient() + .on("POST", "http://example.com/negotiate?negotiateVersion=1", + (req) -> { + header.set(req.getHeaders().get("User-Agent")); + return Single.just(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\"" + + "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")); + }); + + MockTransport transport = new MockTransport(); + HubConnection hubConnection = HubConnectionBuilder.create("http://example.com") + .withTransportImplementation(transport) + .withHttpClient(client) + .withHeader("User-Agent", "Updated Value") + .build(); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); + hubConnection.stop(); + assertEquals("Updated Value", header.get()); + } + + @Test + public void userAgentCanBeCleared() { + AtomicReference<String> header = new AtomicReference<>(); + TestHttpClient client = new TestHttpClient() + .on("POST", "http://example.com/negotiate?negotiateVersion=1", + (req) -> { + header.set(req.getHeaders().get("User-Agent")); + return Single.just(new HttpResponse(200, "", "{\"connectionId\":\"bVOiRPG8-6YiJ6d7ZcTOVQ\",\"" + + "availableTransports\":[{\"transport\":\"WebSockets\",\"transferFormats\":[\"Text\",\"Binary\"]}]}")); + }); + + MockTransport transport = new MockTransport(); + HubConnection hubConnection = HubConnectionBuilder.create("http://example.com") + .withTransportImplementation(transport) + .withHttpClient(client) + .withHeader("User-Agent", "") + .build(); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + assertEquals(HubConnectionState.CONNECTED, hubConnection.getConnectionState()); + hubConnection.stop(); + assertEquals("", header.get()); + } @Test public void headersAreSetAndSentThroughBuilder() { AtomicReference<String> header = new AtomicReference<>(); diff --git a/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/UserAgentTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/UserAgentTest.java new file mode 100644 index 0000000000..1a4256897c --- /dev/null +++ b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/UserAgentTest.java @@ -0,0 +1,67 @@ +// 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. + +package com.microsoft.signalr; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class UserAgentTest { + + private static Stream<Arguments> Versions() { + return Stream.of( + Arguments.of("1.0.0", "1.0"), + Arguments.of("3.1.4-preview9-12345", "3.1"), + Arguments.of("3.1.4-preview9-12345-extrastuff", "3.1"), + Arguments.of("99.99.99-dev", "99.99")); + } + + @ParameterizedTest + @MethodSource("Versions") + public void getVersionFromDetailedVersion(String detailedVersion, String version) { + assertEquals(version, UserAgentHelper.getVersion(detailedVersion)); + } + + @Test + public void verifyJavaVendor() { + assertEquals(System.getProperty("java.vendor"), UserAgentHelper.getJavaVendor()); + } + + @Test + public void verifyJavaVersion() { + assertEquals(System.getProperty("java.version"), UserAgentHelper.getJavaVersion()); + } + + @Test + public void checkUserAgentString() { + String userAgent = UserAgentHelper.createUserAgentString(); + assertNotNull(userAgent); + + String detailedVersion = Version.getDetailedVersion(); + String handMadeUserAgent = "Microsoft SignalR/" + UserAgentHelper.getVersion(detailedVersion) + + " (" + detailedVersion + "; " + UserAgentHelper.getOS() + "; Java; " + + UserAgentHelper.getJavaVersion() + "; " + UserAgentHelper.getJavaVendor() + ")"; + + assertEquals(handMadeUserAgent, userAgent); + } + + @ParameterizedTest + @MethodSource("UserAgents") + public void UserAgentHeaderIsCorrect(String detailedVersion, String os, String runtime, String runtimeVersion, String vendor, String expected) { + assertEquals(expected, UserAgentHelper.constructUserAgentString(detailedVersion, os, runtime, runtimeVersion, vendor)); + } + + private static Stream<Arguments> UserAgents() { + return Stream.of( + Arguments.of("1.4.5-dev", "Windows NT", "Java", "7.0.1", "Oracle", "Microsoft SignalR/1.4 (1.4.5-dev; Windows NT; Java; 7.0.1; Oracle)"), + Arguments.of("3.1.0", "", "Java", "7.0.1", "", "Microsoft SignalR/3.1 (3.1.0; Unknown OS; Java; 7.0.1; Unknown Vendor)"), + Arguments.of("5.0.2", "macOS", "Java", "", "Android", "Microsoft SignalR/5.0 (5.0.2; macOS; Java; Unknown Runtime Version; Android)")); + } +} diff --git a/src/SignalR/clients/ts/FunctionalTests/EchoConnectionHandler.cs b/src/SignalR/clients/ts/FunctionalTests/EchoConnectionHandler.cs index 646d328a5b..8dbdfd28f8 100644 --- a/src/SignalR/clients/ts/FunctionalTests/EchoConnectionHandler.cs +++ b/src/SignalR/clients/ts/FunctionalTests/EchoConnectionHandler.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Http.Connections; namespace FunctionalTests { @@ -11,6 +12,13 @@ namespace FunctionalTests { public async override Task OnConnectedAsync(ConnectionContext connection) { + var context = connection.GetHttpContext(); + // The 'withCredentials' tests wont send a cookie for cross-site requests + if (!context.WebSockets.IsWebSocketRequest && !context.Request.Cookies.ContainsKey("testCookie")) + { + return; + } + while (true) { var result = await connection.Transport.Input.ReadAsync(); diff --git a/src/SignalR/clients/ts/FunctionalTests/Startup.cs b/src/SignalR/clients/ts/FunctionalTests/Startup.cs index a7ad5a3886..747d99305d 100644 --- a/src/SignalR/clients/ts/FunctionalTests/Startup.cs +++ b/src/SignalR/clients/ts/FunctionalTests/Startup.cs @@ -136,7 +136,7 @@ namespace FunctionalTests } } - if (string.Equals(context.Request.Method, "OPTIONS", StringComparison.OrdinalIgnoreCase)) + if (HttpMethods.IsOptions(context.Request.Method)) { context.Response.StatusCode = StatusCodes.Status204NoContent; return Task.CompletedTask; diff --git a/src/SignalR/clients/ts/FunctionalTests/TestHub.cs b/src/SignalR/clients/ts/FunctionalTests/TestHub.cs index 5bd4732c1a..04d88409a4 100644 --- a/src/SignalR/clients/ts/FunctionalTests/TestHub.cs +++ b/src/SignalR/clients/ts/FunctionalTests/TestHub.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http.Connections; using Microsoft.AspNetCore.Http.Connections.Features; using Microsoft.AspNetCore.SignalR; +using Microsoft.Net.Http.Headers; namespace FunctionalTests { @@ -136,6 +137,11 @@ namespace FunctionalTests return Context.GetHttpContext().Request.Headers["Content-Type"]; } + public string GetHeader(string headerName) + { + return Context.GetHttpContext().Request.Headers[headerName]; + } + public string GetCookie(string cookieName) { var cookies = Context.GetHttpContext().Request.Cookies; diff --git a/src/SignalR/clients/ts/FunctionalTests/scripts/run-tests.ts b/src/SignalR/clients/ts/FunctionalTests/scripts/run-tests.ts index 5720a4e30e..ad6f65db08 100644 --- a/src/SignalR/clients/ts/FunctionalTests/scripts/run-tests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/scripts/run-tests.ts @@ -245,7 +245,7 @@ function runJest(httpsUrl: string, httpUrl: string) { (async () => { try { - const serverPath = path.resolve(ARTIFACTS_DIR, "bin", "SignalR.Client.FunctionalTestApp", configuration, "netcoreapp3.1", "SignalR.Client.FunctionalTestApp.dll"); + const serverPath = path.resolve(ARTIFACTS_DIR, "bin", "SignalR.Client.FunctionalTestApp", configuration, "netcoreapp5.0", "SignalR.Client.FunctionalTestApp.dll"); debug(`Launching Functional Test Server: ${serverPath}`); let desiredServerUrl = "https://127.0.0.1:0;http://127.0.0.1:0"; diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts index 2bb33c1c11..c66bff8e49 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts @@ -1,8 +1,14 @@ // 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. -import { HttpTransportType, IHubProtocol, JsonHubProtocol } from "@microsoft/signalr"; +import { HttpClient, HttpTransportType, IHubProtocol, JsonHubProtocol } from "@microsoft/signalr"; import { MessagePackHubProtocol } from "@microsoft/signalr-protocol-msgpack"; +import { TestLogger } from "./TestLogger"; + +import { FetchHttpClient } from "@microsoft/signalr/dist/esm/FetchHttpClient"; +import { NodeHttpClient } from "@microsoft/signalr/dist/esm/NodeHttpClient"; +import { Platform } from "@microsoft/signalr/dist/esm/Utils"; +import { XhrHttpClient } from "@microsoft/signalr/dist/esm/XhrHttpClient"; // On slower CI machines, these tests sometimes take longer than 5s jasmine.DEFAULT_TIMEOUT_INTERVAL = 20 * 1000; @@ -97,6 +103,34 @@ export function eachTransportAndProtocol(action: (transport: HttpTransportType, }); } +export function eachTransportAndProtocolAndHttpClient(action: (transport: HttpTransportType, protocol: IHubProtocol, httpClient: HttpClient) => void) { + eachTransportAndProtocol((transport, protocol) => { + getHttpClients().forEach((httpClient) => { + action(transport, protocol, httpClient); + }); + }); +} + export function getGlobalObject(): any { return typeof window !== "undefined" ? window : global; } + +export function getHttpClients(): HttpClient[] { + const httpClients: HttpClient[] = []; + if (typeof XMLHttpRequest !== "undefined") { + httpClients.push(new XhrHttpClient(TestLogger.instance)); + } + if (typeof fetch !== "undefined") { + httpClients.push(new FetchHttpClient(TestLogger.instance)); + } + if (Platform.isNode) { + httpClients.push(new NodeHttpClient(TestLogger.instance)); + } + return httpClients; +} + +export function eachHttpClient(action: (transport: HttpClient) => void) { + return getHttpClients().forEach((t) => { + return action(t); + }); +} diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts index 7760294123..14c1091b49 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts @@ -5,11 +5,12 @@ // tslint:disable:no-floating-promises import { HttpTransportType, IHttpConnectionOptions, TransferFormat } from "@microsoft/signalr"; -import { eachTransport, ECHOENDPOINT_URL } from "./Common"; +import { eachHttpClient, eachTransport, ECHOENDPOINT_URL } from "./Common"; import { TestLogger } from "./TestLogger"; // We want to continue testing HttpConnection, but we don't export it anymore. So just pull it in directly from the source file. import { HttpConnection } from "@microsoft/signalr/dist/esm/HttpConnection"; +import { Platform } from "@microsoft/signalr/dist/esm/Utils"; import "./LogBannerReporter"; const commonOptions: IHttpConnectionOptions = { @@ -44,110 +45,150 @@ describe("connection", () => { }); eachTransport((transportType) => { - describe(`over ${HttpTransportType[transportType]}`, () => { - it("can send and receive messages", (done) => { - const message = "Hello World!"; - // the url should be resolved relative to the document.location.host - // and the leading '/' should be automatically added to the url - const connection = new HttpConnection(ECHOENDPOINT_URL, { - ...commonOptions, - transport: transportType, - }); + eachHttpClient((httpClient) => { + describe(`over ${HttpTransportType[transportType]} with ${(httpClient.constructor as any).name}`, () => { + it("can send and receive messages", (done) => { + const message = "Hello World!"; + // the url should be resolved relative to the document.location.host + // and the leading '/' should be automatically added to the url + const connection = new HttpConnection(ECHOENDPOINT_URL, { + ...commonOptions, + httpClient, + transport: transportType, + }); - connection.onreceive = (data: any) => { - if (data === message) { - connection.stop(); - } - }; - - connection.onclose = (error: any) => { - expect(error).toBeUndefined(); - done(); - }; - - connection.start(TransferFormat.Text).then(() => { - connection.send(message); - }).catch((e: any) => { - fail(e); - done(); - }); - }); - - it("does not log content of messages sent or received by default", (done) => { - TestLogger.saveLogsAndReset(); - const message = "Hello World!"; - - // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is not set. - const connection = new HttpConnection(ECHOENDPOINT_URL, { - logger: TestLogger.instance, - transport: transportType, - }); - - connection.onreceive = (data: any) => { - if (data === message) { - connection.stop(); - } - }; - - // @ts-ignore: We don't use the error parameter intentionally. - connection.onclose = (error) => { - // Search the logs for the message content - expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); - // @ts-ignore: We don't use the _ or __ parameters intentionally. - for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { - expect(logMessage).not.toContain(message); - } - done(); - }; - - connection.start(TransferFormat.Text).then(() => { - connection.send(message); - }).catch((e) => { - fail(e); - done(); - }); - }); - - it("does log content of messages sent or received when enabled", (done) => { - TestLogger.saveLogsAndReset(); - const message = "Hello World!"; - - // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is set to true (even if commonOptions changes). - const connection = new HttpConnection(ECHOENDPOINT_URL, { - logMessageContent: true, - logger: TestLogger.instance, - transport: transportType, - }); - - connection.onreceive = (data: any) => { - if (data === message) { - connection.stop(); - } - }; - - // @ts-ignore: We don't use the error parameter intentionally. - connection.onclose = (error) => { - // Search the logs for the message content - let matches = 0; - expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); - // @ts-ignore: We don't use the _ or __ parameters intentionally. - for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { - if (logMessage.indexOf(message) !== -1) { - matches += 1; + connection.onreceive = (data: any) => { + if (data === message) { + connection.stop(); } - } + }; - // One match for send, one for receive. - expect(matches).toEqual(2); - done(); - }; + connection.onclose = (error: any) => { + expect(error).toBeUndefined(); + done(); + }; - connection.start(TransferFormat.Text).then(() => { - connection.send(message); - }).catch((e: any) => { - fail(e); - done(); + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e: any) => { + fail(e); + done(); + }); }); + + it("does not log content of messages sent or received by default", (done) => { + TestLogger.saveLogsAndReset(); + const message = "Hello World!"; + + // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is not set. + const connection = new HttpConnection(ECHOENDPOINT_URL, { + httpClient, + logger: TestLogger.instance, + transport: transportType, + }); + + connection.onreceive = (data: any) => { + if (data === message) { + connection.stop(); + } + }; + + // @ts-ignore: We don't use the error parameter intentionally. + connection.onclose = (error) => { + // Search the logs for the message content + expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); + // @ts-ignore: We don't use the _ or __ parameters intentionally. + for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { + expect(logMessage).not.toContain(message); + } + done(); + }; + + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e) => { + fail(e); + done(); + }); + }); + + it("does log content of messages sent or received when enabled", (done) => { + TestLogger.saveLogsAndReset(); + const message = "Hello World!"; + + // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is set to true (even if commonOptions changes). + const connection = new HttpConnection(ECHOENDPOINT_URL, { + httpClient, + logMessageContent: true, + logger: TestLogger.instance, + transport: transportType, + }); + + connection.onreceive = (data: any) => { + if (data === message) { + connection.stop(); + } + }; + + // @ts-ignore: We don't use the error parameter intentionally. + connection.onclose = (error) => { + // Search the logs for the message content + let matches = 0; + expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); + // @ts-ignore: We don't use the _ or __ parameters intentionally. + for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { + if (logMessage.indexOf(message) !== -1) { + matches += 1; + } + } + + // One match for send, one for receive. + expect(matches).toEqual(2); + done(); + }; + + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e: any) => { + fail(e); + done(); + }); + }); + + // withCredentials doesn't make sense in Node or when using WebSockets + if (!Platform.isNode && transportType !== HttpTransportType.WebSockets && + // tests run through karma during automation which is cross-site, but manually running the server will result in these tests failing + // so we check for cross-site + !(window && ECHOENDPOINT_URL.match(`^${window.location.href}`))) { + it("honors withCredentials flag", (done) => { + TestLogger.saveLogsAndReset(); + const message = "Hello World!"; + + // The server will set some response headers for the '/negotiate' endpoint + const connection = new HttpConnection(ECHOENDPOINT_URL, { + ...commonOptions, + httpClient, + transport: transportType, + withCredentials: false, + }); + + connection.onreceive = (data: any) => { + fail(new Error(`Unexpected messaged received '${data}'.`)); + }; + + // @ts-ignore: We don't use the error parameter intentionally. + connection.onclose = (error) => { + done(); + }; + + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e: any) => { + fail(e); + done(); + }); + }); + } }); }); }); diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts index 3d5f434a17..61b43e0654 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts @@ -6,8 +6,9 @@ import { AbortError, DefaultHttpClient, HttpClient, HttpRequest, HttpResponse, HttpTransportType, HubConnectionBuilder, IHttpConnectionOptions, JsonHubProtocol, NullLogger } from "@microsoft/signalr"; import { MessagePackHubProtocol } from "@microsoft/signalr-protocol-msgpack"; +import { getUserAgentHeader, Platform } from "@microsoft/signalr/dist/esm/Utils"; -import { eachTransport, eachTransportAndProtocol, ENDPOINT_BASE_HTTPS_URL, ENDPOINT_BASE_URL } from "./Common"; +import { eachTransport, eachTransportAndProtocolAndHttpClient, ENDPOINT_BASE_HTTPS_URL, ENDPOINT_BASE_URL } from "./Common"; import "./LogBannerReporter"; import { TestLogger } from "./TestLogger"; @@ -49,12 +50,12 @@ function getConnectionBuilder(transportType?: HttpTransportType, url?: string, o } describe("hubConnection", () => { - eachTransportAndProtocol((transportType, protocol) => { + eachTransportAndProtocolAndHttpClient((transportType, protocol, httpClient) => { describe("using " + protocol.name + " over " + HttpTransportType[transportType] + " transport", () => { it("can invoke server method and receive result", (done) => { const message = "你好,世界!"; - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -81,7 +82,7 @@ describe("hubConnection", () => { it("using https, can invoke server method and receive result", (done) => { const message = "你好,世界!"; - const hubConnection = getConnectionBuilder(transportType, TESTHUBENDPOINT_HTTPS_URL) + const hubConnection = getConnectionBuilder(transportType, TESTHUBENDPOINT_HTTPS_URL, { httpClient }) .withHubProtocol(protocol) .build(); @@ -108,7 +109,7 @@ describe("hubConnection", () => { it("can invoke server method non-blocking and not receive result", (done) => { const message = "你好,世界!"; - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -130,7 +131,7 @@ describe("hubConnection", () => { }); it("can invoke server method structural object and receive structural result", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -154,7 +155,7 @@ describe("hubConnection", () => { }); it("can stream server method and receive result", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -185,7 +186,7 @@ describe("hubConnection", () => { }); it("can stream server method and cancel stream", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -219,7 +220,7 @@ describe("hubConnection", () => { it("rethrows an exception from the server when invoking", (done) => { const errorMessage = "An unexpected error occurred invoking 'ThrowException' on the server. InvalidOperationException: An error occurred."; - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -241,7 +242,7 @@ describe("hubConnection", () => { }); it("throws an exception when invoking streaming method with invoke", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -263,7 +264,7 @@ describe("hubConnection", () => { }); it("throws an exception when receiving a streaming result for method called with invoke", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -286,7 +287,7 @@ describe("hubConnection", () => { it("rethrows an exception from the server when streaming", (done) => { const errorMessage = "An unexpected error occurred invoking 'StreamThrowException' on the server. InvalidOperationException: An error occurred."; - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -313,7 +314,7 @@ describe("hubConnection", () => { }); it("throws an exception when invoking hub method with stream", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -340,7 +341,7 @@ describe("hubConnection", () => { }); it("can receive server calls", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -370,7 +371,7 @@ describe("hubConnection", () => { }); it("can receive server calls without rebinding handler when restarted", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -425,7 +426,7 @@ describe("hubConnection", () => { }); it("closed with error or start fails if hub cannot be created", async (done) => { - const hubConnection = getConnectionBuilder(transportType, ENDPOINT_BASE_URL + "/uncreatable") + const hubConnection = getConnectionBuilder(transportType, ENDPOINT_BASE_URL + "/uncreatable", { httpClient }) .withHubProtocol(protocol) .build(); @@ -446,7 +447,7 @@ describe("hubConnection", () => { }); it("can handle different types", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -489,7 +490,7 @@ describe("hubConnection", () => { }); it("can receive different types", (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -534,7 +535,7 @@ describe("hubConnection", () => { it("can be restarted", (done) => { const message = "你好,世界!"; - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -577,7 +578,7 @@ describe("hubConnection", () => { }); it("can stream from client to server with rxjs", async (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -594,7 +595,7 @@ describe("hubConnection", () => { }); it("can stream from client to server and close with error with rxjs", async (done) => { - const hubConnection = getConnectionBuilder(transportType) + const hubConnection = getConnectionBuilder(transportType, undefined, { httpClient }) .withHubProtocol(protocol) .build(); @@ -1092,6 +1093,33 @@ describe("hubConnection", () => { } }); + eachTransport((t) => { + it("sets the user agent header", async (done) => { + const hubConnection = getConnectionBuilder(t, TESTHUBENDPOINT_URL) + .withHubProtocol(new JsonHubProtocol()) + .build(); + + try { + await hubConnection.start(); + + // Check to see that the Content-Type header is set the expected value + const [name, value] = getUserAgentHeader(); + const headerValue = await hubConnection.invoke("GetHeader", name); + + if ((t === HttpTransportType.ServerSentEvents || t === HttpTransportType.WebSockets) && !Platform.isNode) { + expect(headerValue).toBeNull(); + } else { + expect(headerValue).toEqual(value); + } + + await hubConnection.stop(); + done(); + } catch (e) { + fail(e); + } + }); + }); + function getJwtToken(url: string): Promise<string> { return new Promise((resolve, reject) => { const httpClient = new DefaultHttpClient(NullLogger.instance); diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/README.md b/src/SignalR/clients/ts/signalr-protocol-msgpack/README.md index e840374319..d7687bcff6 100644 --- a/src/SignalR/clients/ts/signalr-protocol-msgpack/README.md +++ b/src/SignalR/clients/ts/signalr-protocol-msgpack/README.md @@ -4,15 +4,21 @@ MsgPack support for SignalR for ASP.NET Core ```bash npm install @microsoft/signalr-protocol-msgpack -``` -or -```bash +# or yarn add @microsoft/signalr-protocol-msgpack ``` +To try previews of the next version, use the `next` tag on NPM: + +```bash +npm install @microsoft/signalr-protocol-msgpack@next +# or +yarn add @microsoft/signalr-protocol-msgpack@next +``` + ## Usage -See the [SignalR Documentation](https://docs.microsoft.com/en-us/aspnet/core/signalr) at docs.microsoft.com for documentation on the latest release. [API Reference Documentation](https://docs.microsoft.com/javascript/api/%40aspnet/signalr-protocol-msgpack/?view=signalr-js-latest) is also available on docs.microsoft.com. +See the [SignalR Documentation](https://docs.microsoft.com/aspnet/core/signalr) at docs.microsoft.com for documentation on the latest release. [API Reference Documentation](https://docs.microsoft.com/javascript/api/%40aspnet/signalr-protocol-msgpack/?view=signalr-js-latest) is also available on docs.microsoft.com. ### Browser diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json index 3d262cc056..58e4966e10 100644 --- a/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json +++ b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/signalr-protocol-msgpack", - "version": "3.0.0-dev", + "version": "5.0.0-dev", "description": "MsgPack Protocol support for ASP.NET Core SignalR", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", @@ -29,14 +29,14 @@ ], "repository": { "type": "git", - "url": "git+https://github.com/aspnet/AspNetCore.git" + "url": "git+https://github.com/dotnet/aspnetcore.git" }, "author": "Microsoft", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/aspnet/AspNetCore/issues" + "url": "https://github.com/dotnet/aspnetcore/issues" }, - "homepage": "https://github.com/aspnet/AspNetCore/tree/master/src/SignalR#readme", + "homepage": "https://github.com/dotnet/aspnetcore/tree/master/src/SignalR#readme", "files": [ "dist/**/*", "src/**/*" diff --git a/src/SignalR/clients/ts/signalr-protocol-msgpack/signalr-protocol-msgpack.npmproj b/src/SignalR/clients/ts/signalr-protocol-msgpack/signalr-protocol-msgpack.npmproj index 72978faa2d..1a2b2deac3 100644 --- a/src/SignalR/clients/ts/signalr-protocol-msgpack/signalr-protocol-msgpack.npmproj +++ b/src/SignalR/clients/ts/signalr-protocol-msgpack/signalr-protocol-msgpack.npmproj @@ -13,5 +13,9 @@ <ProjectReference Include="..\signalr\signalr.npmproj" /> </ItemGroup> + <ItemGroup> + <BuildOutputFiles Include="dist\browser\signalr-protocol-msgpack.js" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" /> </Project> diff --git a/src/SignalR/clients/ts/signalr/README.md b/src/SignalR/clients/ts/signalr/README.md index ec8f34b227..921556949e 100644 --- a/src/SignalR/clients/ts/signalr/README.md +++ b/src/SignalR/clients/ts/signalr/README.md @@ -1,18 +1,26 @@ -JavaScript and TypeScript clients for SignalR for ASP.NET Core +JavaScript and TypeScript clients for SignalR for ASP.NET Core and Azure SignalR Service ## Installation ```bash npm install @microsoft/signalr -``` -or -```bash +# or yarn add @microsoft/signalr ``` +To try previews of the next version, use the `next` tag on NPM: + +```bash +npm install @microsoft/signalr@next +# or +yarn add @microsoft/signalr@next +``` + ## Usage -See the [SignalR Documentation](https://docs.microsoft.com/en-us/aspnet/core/signalr) at docs.microsoft.com for documentation on the latest release. [API Reference Documentation](https://docs.microsoft.com/javascript/api/%40aspnet/signalr/?view=signalr-js-latest) is also available on docs.microsoft.com. +See the [SignalR Documentation](https://docs.microsoft.com/aspnet/core/signalr) at docs.microsoft.com for documentation on the latest release. [API Reference Documentation](https://docs.microsoft.com/javascript/api/%40aspnet/signalr/?view=signalr-js-latest) is also available on docs.microsoft.com. + +For documentation on using this client with Azure SignalR Service and Azure Functions, see the [SignalR Service serverless developer guide](https://docs.microsoft.com/azure/azure-signalr/signalr-concept-serverless-development-config). ### Browser diff --git a/src/SignalR/clients/ts/signalr/package.json b/src/SignalR/clients/ts/signalr/package.json index 6b50f24d35..190bdefc1e 100644 --- a/src/SignalR/clients/ts/signalr/package.json +++ b/src/SignalR/clients/ts/signalr/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft/signalr", - "version": "3.0.0-dev", + "version": "5.0.0-dev", "description": "ASP.NET Core SignalR Client", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", @@ -32,14 +32,14 @@ ], "repository": { "type": "git", - "url": "git+https://github.com/aspnet/AspNetCore.git" + "url": "git+https://github.com/dotnet/aspnetcore.git" }, "author": "Microsoft", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/aspnet/AspNetCore/issues" + "url": "https://github.com/dotnet/aspnetcore/issues" }, - "homepage": "https://github.com/aspnet/AspNetCore/tree/master/src/SignalR#readme", + "homepage": "https://github.com/dotnet/aspnetcore/tree/master/src/SignalR#readme", "files": [ "dist/**/*", "src/**/*" diff --git a/src/SignalR/clients/ts/signalr/signalr.npmproj b/src/SignalR/clients/ts/signalr/signalr.npmproj index e6a6c1d993..dbd62e31c6 100644 --- a/src/SignalR/clients/ts/signalr/signalr.npmproj +++ b/src/SignalR/clients/ts/signalr/signalr.npmproj @@ -8,5 +8,10 @@ <IsShippingPackage>true</IsShippingPackage> </PropertyGroup> + <ItemGroup> + <BuildOutputFiles Include="dist\browser\signalr.js" /> + <BuildOutputFiles Include="dist\webworker\signalr.js" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" /> </Project> diff --git a/src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts b/src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts index fece43020d..8058e5716a 100644 --- a/src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts +++ b/src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. import { AbortError } from "./Errors"; +import { FetchHttpClient } from "./FetchHttpClient"; import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient"; import { ILogger } from "./ILogger"; import { NodeHttpClient } from "./NodeHttpClient"; @@ -15,7 +16,9 @@ export class DefaultHttpClient extends HttpClient { public constructor(logger: ILogger) { super(); - if (typeof XMLHttpRequest !== "undefined") { + if (typeof fetch !== "undefined") { + this.httpClient = new FetchHttpClient(logger); + } else if (typeof XMLHttpRequest !== "undefined") { this.httpClient = new XhrHttpClient(logger); } else { this.httpClient = new NodeHttpClient(logger); diff --git a/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts b/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts new file mode 100644 index 0000000000..f446e31ac5 --- /dev/null +++ b/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts @@ -0,0 +1,121 @@ +// 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. + +import { AbortError, HttpError, TimeoutError } from "./Errors"; +import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient"; +import { ILogger, LogLevel } from "./ILogger"; + +export class FetchHttpClient extends HttpClient { + private readonly logger: ILogger; + + public constructor(logger: ILogger) { + super(); + this.logger = logger; + } + + /** @inheritDoc */ + public async send(request: HttpRequest): Promise<HttpResponse> { + // Check that abort was not signaled before calling send + if (request.abortSignal && request.abortSignal.aborted) { + throw new AbortError(); + } + + if (!request.method) { + throw new Error("No method defined."); + } + if (!request.url) { + throw new Error("No url defined."); + } + + const abortController = new AbortController(); + + let error: any; + // Hook our abortSignal into the abort controller + if (request.abortSignal) { + request.abortSignal.onabort = () => { + abortController.abort(); + error = new AbortError(); + }; + } + + // If a timeout has been passed in, setup a timeout to call abort + // Type needs to be any to fit window.setTimeout and NodeJS.setTimeout + let timeoutId: any = null; + if (request.timeout) { + const msTimeout = request.timeout!; + timeoutId = setTimeout(() => { + abortController.abort(); + this.logger.log(LogLevel.Warning, `Timeout from HTTP request.`); + error = new TimeoutError(); + }, msTimeout); + } + + let response: Response; + try { + response = await fetch(request.url!, { + body: request.content!, + cache: "no-cache", + credentials: request.withCredentials === true ? "include" : "same-origin", + headers: { + "Content-Type": "text/plain;charset=UTF-8", + "X-Requested-With": "XMLHttpRequest", + ...request.headers, + }, + method: request.method!, + mode: "cors", + redirect: "manual", + signal: abortController.signal, + }); + } catch (e) { + if (error) { + throw error; + } + this.logger.log( + LogLevel.Warning, + `Error from HTTP request. ${e}.`, + ); + throw e; + } finally { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (request.abortSignal) { + request.abortSignal.onabort = null; + } + } + + if (!response.ok) { + throw new HttpError(response.statusText, response.status); + } + + const content = deserializeContent(response, request.responseType); + const payload = await content; + + return new HttpResponse( + response.status, + response.statusText, + payload, + ); + } +} + +function deserializeContent(response: Response, responseType?: XMLHttpRequestResponseType): Promise<string | ArrayBuffer> { + let content; + switch (responseType) { + case "arraybuffer": + content = response.arrayBuffer(); + break; + case "text": + content = response.text(); + break; + case "blob": + case "document": + case "json": + throw new Error(`${responseType} is not supported.`); + default: + content = response.text(); + break; + } + + return content; +} diff --git a/src/SignalR/clients/ts/signalr/src/HttpClient.ts b/src/SignalR/clients/ts/signalr/src/HttpClient.ts index 9685feca5e..57614bb86b 100644 --- a/src/SignalR/clients/ts/signalr/src/HttpClient.ts +++ b/src/SignalR/clients/ts/signalr/src/HttpClient.ts @@ -25,6 +25,9 @@ export interface HttpRequest { /** The time to wait for the request to complete before throwing a TimeoutError. Measured in milliseconds. */ timeout?: number; + + /** This controls whether credentials such as cookies are sent in cross-site requests. */ + withCredentials?: boolean; } /** Represents an HTTP response. */ @@ -57,6 +60,14 @@ export class HttpResponse { * @param {ArrayBuffer} content The content of the response. */ constructor(statusCode: number, statusText: string, content: ArrayBuffer); + + /** Constructs a new instance of {@link @microsoft/signalr.HttpResponse} with the specified status code, message and binary content. + * + * @param {number} statusCode The status code of the response. + * @param {string} statusText The status message of the response. + * @param {string | ArrayBuffer} content The content of the response. + */ + constructor(statusCode: number, statusText: string, content: string | ArrayBuffer); constructor( public readonly statusCode: number, public readonly statusText?: string, diff --git a/src/SignalR/clients/ts/signalr/src/HttpConnection.ts b/src/SignalR/clients/ts/signalr/src/HttpConnection.ts index 075860006f..65c491a32c 100644 --- a/src/SignalR/clients/ts/signalr/src/HttpConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HttpConnection.ts @@ -9,7 +9,7 @@ import { ILogger, LogLevel } from "./ILogger"; import { HttpTransportType, ITransport, TransferFormat } from "./ITransport"; import { LongPollingTransport } from "./LongPollingTransport"; import { ServerSentEventsTransport } from "./ServerSentEventsTransport"; -import { Arg, createLogger, Platform } from "./Utils"; +import { Arg, createLogger, getUserAgentHeader, Platform } from "./Utils"; import { WebSocketTransport } from "./WebSocketTransport"; /** @private */ @@ -81,7 +81,12 @@ export class HttpConnection implements IConnection { this.baseUrl = this.resolveUrl(url); options = options || {}; - options.logMessageContent = options.logMessageContent || false; + options.logMessageContent = options.logMessageContent === undefined ? false : options.logMessageContent; + if (typeof options.withCredentials === "boolean" || options.withCredentials === undefined) { + options.withCredentials = options.withCredentials === undefined ? true : options.withCredentials; + } else { + throw new Error("withCredentials option was not a 'boolean' or 'undefined' value"); + } if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) { options.WebSocket = WebSocket; @@ -302,26 +307,28 @@ export class HttpConnection implements IConnection { } private async getNegotiationResponse(url: string): Promise<INegotiateResponse> { - let headers; + const headers = {}; if (this.accessTokenFactory) { const token = await this.accessTokenFactory(); if (token) { - headers = { - ["Authorization"]: `Bearer ${token}`, - }; + headers[`Authorization`] = `Bearer ${token}`; } } + const [name, value] = getUserAgentHeader(); + headers[name] = value; + const negotiateUrl = this.resolveNegotiateUrl(url); this.logger.log(LogLevel.Debug, `Sending negotiation request: ${negotiateUrl}.`); try { const response = await this.httpClient.post(negotiateUrl, { content: "", headers, + withCredentials: this.options.withCredentials, }); if (response.statusCode !== 200) { - return Promise.reject(new Error(`Unexpected status code returned from negotiate ${response.statusCode}`)); + return Promise.reject(new Error(`Unexpected status code returned from negotiate '${response.statusCode}'`)); } const negotiateResponse = JSON.parse(response.content as string) as INegotiateResponse; @@ -409,9 +416,9 @@ export class HttpConnection implements IConnection { if (!this.options.EventSource) { throw new Error("'EventSource' is not supported in your environment."); } - return new ServerSentEventsTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.EventSource); + return new ServerSentEventsTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.EventSource, this.options.withCredentials!); case HttpTransportType.LongPolling: - return new LongPollingTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false); + return new LongPollingTransport(this.httpClient, this.accessTokenFactory, this.logger, this.options.logMessageContent || false, this.options.withCredentials!); default: throw new Error(`Unknown transport: ${transport}.`); } @@ -474,8 +481,8 @@ export class HttpConnection implements IConnection { } if (this.connectionState === ConnectionState.Connecting) { - this.logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection hasn't yet left the in the connecting state.`); - return; + this.logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is still in the connecting state.`); + throw new Error(`HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.`); } if (this.connectionState === ConnectionState.Disconnecting) { @@ -626,7 +633,7 @@ export class TransportSendQueue { offset += item.byteLength; } - return result; + return result.buffer; } } diff --git a/src/SignalR/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts index 62190c166c..0435a92300 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnection.ts @@ -599,6 +599,10 @@ export class HubConnection { } private resetKeepAliveInterval() { + if (this.connection.features.inherentKeepAlive) { + return; + } + this.cleanupPingTimer(); this.pingServerHandle = setTimeout(async () => { if (this.connectionState === HubConnectionState.Connected) { diff --git a/src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts b/src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts index 98a23a3b3d..fa5d7432b9 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts @@ -70,14 +70,14 @@ export class HubConnectionBuilder { /** Configures custom logging for the {@link @microsoft/signalr.HubConnection}. * * @param {string} logLevel A string representing a LogLevel setting a minimum level of messages to log. - * See {@link https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details. + * See {@link https://docs.microsoft.com/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details. */ public configureLogging(logLevel: string): HubConnectionBuilder; /** Configures custom logging for the {@link @microsoft/signalr.HubConnection}. * * @param {LogLevel | string | ILogger} logging A {@link @microsoft/signalr.LogLevel}, a string representing a LogLevel, or an object implementing the {@link @microsoft/signalr.ILogger} interface. - * See {@link https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details. + * See {@link https://docs.microsoft.com/aspnet/core/signalr/configuration#configure-logging|the documentation for client logging configuration} for more details. * @returns The {@link @microsoft/signalr.HubConnectionBuilder} instance, for chaining. */ public configureLogging(logging: LogLevel | string | ILogger): HubConnectionBuilder; diff --git a/src/SignalR/clients/ts/signalr/src/IHttpConnectionOptions.ts b/src/SignalR/clients/ts/signalr/src/IHttpConnectionOptions.ts index a980370b64..128872722b 100644 --- a/src/SignalR/clients/ts/signalr/src/IHttpConnectionOptions.ts +++ b/src/SignalR/clients/ts/signalr/src/IHttpConnectionOptions.ts @@ -53,4 +53,12 @@ export interface IHttpConnectionOptions { * @internal */ EventSource?: EventSourceConstructor; + + /** + * Default value is 'true'. + * This controls whether credentials such as cookies are sent in cross-site requests. + * + * Cookies are used by many load-balancers for sticky sessions which is required when your app is deployed with multiple servers. + */ + withCredentials?: boolean; } diff --git a/src/SignalR/clients/ts/signalr/src/LongPollingTransport.ts b/src/SignalR/clients/ts/signalr/src/LongPollingTransport.ts index 7ad1c7d129..f7a7da1784 100644 --- a/src/SignalR/clients/ts/signalr/src/LongPollingTransport.ts +++ b/src/SignalR/clients/ts/signalr/src/LongPollingTransport.ts @@ -6,7 +6,7 @@ import { HttpError, TimeoutError } from "./Errors"; import { HttpClient, HttpRequest } from "./HttpClient"; import { ILogger, LogLevel } from "./ILogger"; import { ITransport, TransferFormat } from "./ITransport"; -import { Arg, getDataDetail, sendMessage } from "./Utils"; +import { Arg, getDataDetail, getUserAgentHeader, sendMessage } from "./Utils"; // Not exported from 'index', this type is internal. /** @private */ @@ -15,6 +15,7 @@ export class LongPollingTransport implements ITransport { private readonly accessTokenFactory: (() => string | Promise<string>) | undefined; private readonly logger: ILogger; private readonly logMessageContent: boolean; + private readonly withCredentials: boolean; private readonly pollAbort: AbortController; private url?: string; @@ -30,12 +31,13 @@ export class LongPollingTransport implements ITransport { return this.pollAbort.aborted; } - constructor(httpClient: HttpClient, accessTokenFactory: (() => string | Promise<string>) | undefined, logger: ILogger, logMessageContent: boolean) { + constructor(httpClient: HttpClient, accessTokenFactory: (() => string | Promise<string>) | undefined, logger: ILogger, logMessageContent: boolean, withCredentials: boolean) { this.httpClient = httpClient; this.accessTokenFactory = accessTokenFactory; this.logger = logger; this.pollAbort = new AbortController(); this.logMessageContent = logMessageContent; + this.withCredentials = withCredentials; this.running = false; @@ -58,10 +60,15 @@ export class LongPollingTransport implements ITransport { throw new Error("Binary protocols over XmlHttpRequest not implementing advanced features are not supported."); } + const headers = {}; + const [name, value] = getUserAgentHeader(); + headers[name] = value; + const pollOptions: HttpRequest = { abortSignal: this.pollAbort.signal, - headers: {}, + headers, timeout: 100000, + withCredentials: this.withCredentials, }; if (transferFormat === TransferFormat.Binary) { @@ -178,7 +185,7 @@ export class LongPollingTransport implements ITransport { if (!this.running) { return Promise.reject(new Error("Cannot send until the transport is connected")); } - return sendMessage(this.logger, "LongPolling", this.httpClient, this.url!, this.accessTokenFactory, data, this.logMessageContent); + return sendMessage(this.logger, "LongPolling", this.httpClient, this.url!, this.accessTokenFactory, data, this.logMessageContent, this.withCredentials); } public async stop(): Promise<void> { @@ -194,8 +201,13 @@ export class LongPollingTransport implements ITransport { // Send DELETE to clean up long polling on the server this.logger.log(LogLevel.Trace, `(LongPolling transport) sending DELETE request to ${this.url}.`); + const headers = {}; + const [name, value] = getUserAgentHeader(); + headers[name] = value; + const deleteOptions: HttpRequest = { - headers: {}, + headers, + withCredentials: this.withCredentials, }; const token = await this.getAccessToken(); this.updateHeaderToken(deleteOptions, token); diff --git a/src/SignalR/clients/ts/signalr/src/ServerSentEventsTransport.ts b/src/SignalR/clients/ts/signalr/src/ServerSentEventsTransport.ts index 09463c5e70..de4bf3e2b7 100644 --- a/src/SignalR/clients/ts/signalr/src/ServerSentEventsTransport.ts +++ b/src/SignalR/clients/ts/signalr/src/ServerSentEventsTransport.ts @@ -5,7 +5,7 @@ import { HttpClient } from "./HttpClient"; import { ILogger, LogLevel } from "./ILogger"; import { ITransport, TransferFormat } from "./ITransport"; import { EventSourceConstructor } from "./Polyfills"; -import { Arg, getDataDetail, Platform, sendMessage } from "./Utils"; +import { Arg, getDataDetail, getUserAgentHeader, Platform, sendMessage } from "./Utils"; /** @private */ export class ServerSentEventsTransport implements ITransport { @@ -13,6 +13,7 @@ export class ServerSentEventsTransport implements ITransport { private readonly accessTokenFactory: (() => string | Promise<string>) | undefined; private readonly logger: ILogger; private readonly logMessageContent: boolean; + private readonly withCredentials: boolean; private readonly eventSourceConstructor: EventSourceConstructor; private eventSource?: EventSource; private url?: string; @@ -21,11 +22,12 @@ export class ServerSentEventsTransport implements ITransport { public onclose: ((error?: Error) => void) | null; constructor(httpClient: HttpClient, accessTokenFactory: (() => string | Promise<string>) | undefined, logger: ILogger, - logMessageContent: boolean, eventSourceConstructor: EventSourceConstructor) { + logMessageContent: boolean, eventSourceConstructor: EventSourceConstructor, withCredentials: boolean) { this.httpClient = httpClient; this.accessTokenFactory = accessTokenFactory; this.logger = logger; this.logMessageContent = logMessageContent; + this.withCredentials = withCredentials; this.eventSourceConstructor = eventSourceConstructor; this.onreceive = null; @@ -58,11 +60,17 @@ export class ServerSentEventsTransport implements ITransport { let eventSource: EventSource; if (Platform.isBrowser || Platform.isWebWorker) { - eventSource = new this.eventSourceConstructor(url, { withCredentials: true }); + eventSource = new this.eventSourceConstructor(url, { withCredentials: this.withCredentials }); } else { // Non-browser passes cookies via the dictionary const cookies = this.httpClient.getCookieString(url); - eventSource = new this.eventSourceConstructor(url, { withCredentials: true, headers: { Cookie: cookies } } as EventSourceInit); + const headers = { + Cookie: cookies, + }; + const [name, value] = getUserAgentHeader(); + headers[name] = value; + + eventSource = new this.eventSourceConstructor(url, { withCredentials: this.withCredentials, headers } as EventSourceInit); } try { @@ -104,7 +112,7 @@ export class ServerSentEventsTransport implements ITransport { if (!this.eventSource) { return Promise.reject(new Error("Cannot send until the transport is connected")); } - return sendMessage(this.logger, "SSE", this.httpClient, this.url!, this.accessTokenFactory, data, this.logMessageContent); + return sendMessage(this.logger, "SSE", this.httpClient, this.url!, this.accessTokenFactory, data, this.logMessageContent, this.withCredentials); } public stop(): Promise<void> { diff --git a/src/SignalR/clients/ts/signalr/src/Utils.ts b/src/SignalR/clients/ts/signalr/src/Utils.ts index 1233ce6c51..3f7318cd68 100644 --- a/src/SignalR/clients/ts/signalr/src/Utils.ts +++ b/src/SignalR/clients/ts/signalr/src/Utils.ts @@ -7,6 +7,10 @@ import { NullLogger } from "./Loggers"; import { IStreamSubscriber, ISubscription } from "./Stream"; import { Subject } from "./Subject"; +// Version token that will be replaced by the prepack command +/** The version of the SignalR client. */ +export const VERSION: string = "0.0.0-DEV_BUILD"; + /** @private */ export class Arg { public static isRequired(val: any, name: string): void { @@ -25,7 +29,6 @@ export class Arg { /** @private */ export class Platform { - public static get isBrowser(): boolean { return typeof window === "object"; } @@ -81,8 +84,9 @@ export function isArrayBuffer(val: any): val is ArrayBuffer { } /** @private */ -export async function sendMessage(logger: ILogger, transportName: string, httpClient: HttpClient, url: string, accessTokenFactory: (() => string | Promise<string>) | undefined, content: string | ArrayBuffer, logMessageContent: boolean): Promise<void> { - let headers; +export async function sendMessage(logger: ILogger, transportName: string, httpClient: HttpClient, url: string, accessTokenFactory: (() => string | Promise<string>) | undefined, + content: string | ArrayBuffer, logMessageContent: boolean, withCredentials: boolean): Promise<void> { + let headers = {}; if (accessTokenFactory) { const token = await accessTokenFactory(); if (token) { @@ -92,6 +96,9 @@ export async function sendMessage(logger: ILogger, transportName: string, httpCl } } + const [name, value] = getUserAgentHeader(); + headers[name] = value; + logger.log(LogLevel.Trace, `(${transportName} transport) sending data. ${getDataDetail(content, logMessageContent)}.`); const responseType = isArrayBuffer(content) ? "arraybuffer" : "text"; @@ -99,6 +106,7 @@ export async function sendMessage(logger: ILogger, transportName: string, httpCl content, headers, responseType, + withCredentials, }); logger.log(LogLevel.Trace, `(${transportName} transport) request complete. Response status: ${response.statusCode}.`); @@ -181,3 +189,71 @@ export class ConsoleLogger implements ILogger { } } } + +/** @private */ +export function getUserAgentHeader(): [string, string] { + let userAgentHeaderName = "X-SignalR-User-Agent"; + if (Platform.isNode) { + userAgentHeaderName = "User-Agent"; + } + return [ userAgentHeaderName, constructUserAgent(VERSION, getOsName(), getRuntime(), getRuntimeVersion()) ]; +} + +/** @private */ +export function constructUserAgent(version: string, os: string, runtime: string, runtimeVersion: string | undefined): string { + // Microsoft SignalR/[Version] ([Detailed Version]; [Operating System]; [Runtime]; [Runtime Version]) + let userAgent: string = "Microsoft SignalR/"; + + const majorAndMinor = version.split("."); + userAgent += `${majorAndMinor[0]}.${majorAndMinor[1]}`; + userAgent += ` (${version}; `; + + if (os && os !== "") { + userAgent += `${os}; `; + } else { + userAgent += "Unknown OS; "; + } + + userAgent += `${runtime}`; + + if (runtimeVersion) { + userAgent += `; ${runtimeVersion}`; + } else { + userAgent += "; Unknown Runtime Version"; + } + + userAgent += ")"; + return userAgent; +} + +function getOsName(): string { + if (Platform.isNode) { + switch (process.platform) { + case "win32": + return "Windows NT"; + case "darwin": + return "macOS"; + case "linux": + return "Linux"; + default: + return process.platform; + } + } else { + return ""; + } +} + +function getRuntimeVersion(): string | undefined { + if (Platform.isNode) { + return process.versions.node; + } + return undefined; +} + +function getRuntime(): string { + if (Platform.isNode) { + return "NodeJS"; + } else { + return "Browser"; + } +} diff --git a/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts b/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts index 418c306055..d2b65d2039 100644 --- a/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts +++ b/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts @@ -5,7 +5,7 @@ import { HttpClient } from "./HttpClient"; import { ILogger, LogLevel } from "./ILogger"; import { ITransport, TransferFormat } from "./ITransport"; import { WebSocketConstructor } from "./Polyfills"; -import { Arg, getDataDetail, Platform } from "./Utils"; +import { Arg, getDataDetail, getUserAgentHeader, Platform } from "./Utils"; /** @private */ export class WebSocketTransport implements ITransport { @@ -51,12 +51,18 @@ export class WebSocketTransport implements ITransport { const cookies = this.httpClient.getCookieString(url); let opened = false; - if (Platform.isNode && cookies) { + if (Platform.isNode) { + const headers = {}; + const [name, value] = getUserAgentHeader(); + headers[name] = value; + + if (cookies) { + headers[`Cookie`] = `${cookies}`; + } + // Only pass cookies when in non-browser environments webSocket = new this.webSocketConstructor(url, undefined, { - headers: { - Cookie: `${cookies}`, - }, + headers, }); } @@ -92,7 +98,12 @@ export class WebSocketTransport implements ITransport { webSocket.onmessage = (message: MessageEvent) => { this.logger.log(LogLevel.Trace, `(WebSockets transport) data received. ${getDataDetail(message.data, this.logMessageContent)}.`); if (this.onreceive) { - this.onreceive(message.data); + try { + this.onreceive(message.data); + } catch (error) { + this.close(error); + return; + } } }; @@ -143,15 +154,21 @@ export class WebSocketTransport implements ITransport { return Promise.resolve(); } - private close(event?: CloseEvent): void { + private close(event?: CloseEvent | Error): void { // webSocket will be null if the transport did not start successfully this.logger.log(LogLevel.Trace, "(WebSockets transport) socket closed."); if (this.onclose) { - if (event && (event.wasClean === false || event.code !== 1000)) { + if (this.isCloseEvent(event) && (event.wasClean === false || event.code !== 1000)) { this.onclose(new Error(`WebSocket closed with status code: ${event.code} (${event.reason}).`)); + } else if (event instanceof Error) { + this.onclose(event); } else { this.onclose(); } } } + + private isCloseEvent(event?: any): event is CloseEvent { + return event && typeof event.wasClean === "boolean" && typeof event.code === "number"; + } } diff --git a/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts b/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts index 3b27bdded5..41eba9c564 100644 --- a/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts +++ b/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts @@ -31,7 +31,7 @@ export class XhrHttpClient extends HttpClient { const xhr = new XMLHttpRequest(); xhr.open(request.method!, request.url!, true); - xhr.withCredentials = true; + xhr.withCredentials = request.withCredentials === undefined ? true : request.withCredentials; xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); // Explicitly setting the Content-Type header for React Native on Android platform. xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); diff --git a/src/SignalR/clients/ts/signalr/src/index.ts b/src/SignalR/clients/ts/signalr/src/index.ts index dc2086c661..df4e0fba4a 100644 --- a/src/SignalR/clients/ts/signalr/src/index.ts +++ b/src/SignalR/clients/ts/signalr/src/index.ts @@ -1,10 +1,6 @@ // 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. -// Version token that will be replaced by the prepack command -/** The version of the SignalR client. */ -export const VERSION: string = "0.0.0-DEV_BUILD"; - // Everything that users need to access must be exported here. Including interfaces. export { AbortSignal } from "./AbortController"; export { AbortError, HttpError, TimeoutError } from "./Errors"; @@ -22,3 +18,4 @@ export { NullLogger } from "./Loggers"; export { JsonHubProtocol } from "./JsonHubProtocol"; export { Subject } from "./Subject"; export { IRetryPolicy, RetryContext } from "./IRetryPolicy"; +export { VERSION } from "./Utils"; diff --git a/src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts b/src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts index d010fbdbc6..3e0b6a81eb 100644 --- a/src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts +++ b/src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts @@ -5,8 +5,10 @@ import { HttpResponse } from "../src/HttpClient"; import { HttpConnection, INegotiateResponse, TransportSendQueue } from "../src/HttpConnection"; import { IHttpConnectionOptions } from "../src/IHttpConnectionOptions"; import { HttpTransportType, ITransport, TransferFormat } from "../src/ITransport"; +import { getUserAgentHeader } from "../src/Utils"; import { HttpError } from "../src/Errors"; +import { ILogger, LogLevel } from "../src/ILogger"; import { NullLogger } from "../src/Loggers"; import { EventSourceConstructor, WebSocketConstructor } from "../src/Polyfills"; @@ -191,9 +193,9 @@ describe("HttpConnection", () => { const connection = new HttpConnection("http://tempuri.org", options); await expect(connection.start(TransferFormat.Text)) .rejects - .toThrow("Unexpected status code returned from negotiate 999"); + .toThrow("Unexpected status code returned from negotiate '999'"); }, - "Failed to start the connection: Error: Unexpected status code returned from negotiate 999"); + "Failed to start the connection: Error: Unexpected status code returned from negotiate '999'"); }); it("all transport failure errors get aggregated", async () => { @@ -1124,6 +1126,79 @@ describe("HttpConnection", () => { "Failed to start the transport 'WebSockets': Error: There was an error with the transport."); }); + it("user agent header set on negotiate", async () => { + await VerifyLogger.run(async (logger) => { + let userAgentValue: string = ""; + const options: IHttpConnectionOptions = { + ...commonOptions, + httpClient: new TestHttpClient() + .on("POST", (r) => { + userAgentValue = r.headers![`User-Agent`]; + return new HttpResponse(200, "", "{\"error\":\"nope\"}"); + }), + logger, + } as IHttpConnectionOptions; + + const connection = new HttpConnection("http://tempuri.org", options); + try { + await connection.start(TransferFormat.Text); + } catch { + } finally { + await connection.stop(); + } + + const [, value] = getUserAgentHeader(); + expect(userAgentValue).toEqual(value); + }, "Failed to start the connection: Error: nope"); + }); + + it("logMessageContent displays correctly with binary data", async () => { + await VerifyLogger.run(async (logger) => { + const availableTransport = { transport: "LongPolling", transferFormats: ["Text", "Binary"] }; + + let sentMessage = ""; + const captureLogger: ILogger = { + log: (logLevel: LogLevel, message: string) => { + if (logLevel === LogLevel.Trace && message.search("data of length") > 0) { + sentMessage = message; + } + + logger.log(logLevel, message); + }, + }; + + let httpClientGetCount = 0; + const options: IHttpConnectionOptions = { + ...commonOptions, + httpClient: new TestHttpClient() + .on("POST", () => ({ connectionId: "42", availableTransports: [availableTransport] })) + .on("GET", () => { + httpClientGetCount++; + if (httpClientGetCount === 1) { + // First long polling request must succeed so start completes + return ""; + } + return Promise.resolve(); + }) + .on("DELETE", () => new HttpResponse(202)), + logMessageContent: true, + logger: captureLogger, + transport: HttpTransportType.LongPolling, + } as IHttpConnectionOptions; + + const connection = new HttpConnection("http://tempuri.org", options); + connection.onreceive = () => null; + try { + await connection.start(TransferFormat.Binary); + await connection.send(new Uint8Array([0x68, 0x69, 0x20, 0x3a, 0x29])); + } finally { + await connection.stop(); + } + + expect(sentMessage).toBe("(LongPolling transport) sending data. Binary data of length 5. Content: '0x68 0x69 0x20 0x3a 0x29'."); + }); + }); + describe(".constructor", () => { it("throws if no Url is provided", async () => { // Force TypeScript to let us call the constructor incorrectly :) @@ -1386,7 +1461,7 @@ describe("TransportSendQueue", () => { const queue = new TransportSendQueue(transport); - const first = queue.send(new Uint8Array([4, 5, 6])); + const first = queue.send(new Uint8Array([4, 5, 6]).buffer); // This should allow first to enter transport.send promiseSource1.resolve(); // Wait until we're inside transport.send @@ -1401,8 +1476,8 @@ describe("TransportSendQueue", () => { await Promise.all([first, second, third]); expect(sendMock.mock.calls.length).toBe(2); - expect(sendMock.mock.calls[0][0]).toEqual(new Uint8Array([4, 5, 6])); - expect(sendMock.mock.calls[1][0]).toEqual(new Uint8Array([7, 8, 10, 12, 14])); + expect(sendMock.mock.calls[0][0]).toEqual(new Uint8Array([4, 5, 6]).buffer); + expect(sendMock.mock.calls[1][0]).toEqual(new Uint8Array([7, 8, 10, 12, 14]).buffer); await queue.stop(); }); diff --git a/src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts b/src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts index 1cb682cabb..a31f4eeee9 100644 --- a/src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts +++ b/src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts @@ -127,6 +127,25 @@ describe("HubConnection", () => { } }); }); + + it("does not send pings for connection with inherentKeepAlive", async () => { + await VerifyLogger.run(async (logger) => { + const connection = new TestConnection(true, true); + const hubConnection = createHubConnection(connection, logger); + + hubConnection.keepAliveIntervalInMilliseconds = 5; + + try { + await hubConnection.start(); + await delayUntil(500); + + const numPings = connection.sentData.filter((s) => JSON.parse(s).type === MessageType.Ping).length; + expect(numPings).toEqual(0); + } finally { + await hubConnection.stop(); + } + }); + }); }); describe("stop", () => { diff --git a/src/SignalR/clients/ts/signalr/tests/LongPollingTransport.test.ts b/src/SignalR/clients/ts/signalr/tests/LongPollingTransport.test.ts index 2e3dc670e4..853b3527ec 100644 --- a/src/SignalR/clients/ts/signalr/tests/LongPollingTransport.test.ts +++ b/src/SignalR/clients/ts/signalr/tests/LongPollingTransport.test.ts @@ -4,6 +4,7 @@ import { HttpResponse } from "../src/HttpClient"; import { TransferFormat } from "../src/ITransport"; import { LongPollingTransport } from "../src/LongPollingTransport"; +import { getUserAgentHeader } from "../src/Utils"; import { VerifyLogger } from "./Common"; import { TestHttpClient } from "./TestHttpClient"; @@ -39,7 +40,7 @@ describe("LongPollingTransport", () => { } }) .on("DELETE", () => new HttpResponse(202)); - const transport = new LongPollingTransport(client, undefined, logger, false); + const transport = new LongPollingTransport(client, undefined, logger, false, true); await transport.connect("http://example.com", TransferFormat.Text); const stopPromise = transport.stop(); @@ -63,7 +64,7 @@ describe("LongPollingTransport", () => { return new HttpResponse(204); } }); - const transport = new LongPollingTransport(client, undefined, logger, false); + const transport = new LongPollingTransport(client, undefined, logger, false, true); const stopPromise = makeClosedPromise(transport); @@ -96,7 +97,7 @@ describe("LongPollingTransport", () => { return new HttpResponse(202); }); - const transport = new LongPollingTransport(httpClient, undefined, logger, false); + const transport = new LongPollingTransport(httpClient, undefined, logger, false, true); await transport.connect("http://tempuri.org", TransferFormat.Text); @@ -120,6 +121,50 @@ describe("LongPollingTransport", () => { await stopPromise; }); }); + + it("user agent header set on sends and polls", async () => { + await VerifyLogger.run(async (logger) => { + let firstPoll = true; + let firstPollUserAgent = ""; + let secondPollUserAgent = ""; + let deleteUserAgent = ""; + const pollingPromiseSource = new PromiseSource(); + const httpClient = new TestHttpClient() + .on("GET", async (r) => { + if (firstPoll) { + firstPoll = false; + firstPollUserAgent = r.headers![`User-Agent`]; + return new HttpResponse(200); + } else { + secondPollUserAgent = r.headers![`User-Agent`]; + await pollingPromiseSource.promise; + return new HttpResponse(204); + } + }) + .on("DELETE", async (r) => { + deleteUserAgent = r.headers![`User-Agent`]; + return new HttpResponse(202); + }); + + const transport = new LongPollingTransport(httpClient, undefined, logger, false, true); + + await transport.connect("http://tempuri.org", TransferFormat.Text); + + // Begin stopping transport + const stopPromise = transport.stop(); + + // Allow polling to complete + pollingPromiseSource.resolve(); + + // Wait for stop to complete + await stopPromise; + + const [, value] = getUserAgentHeader(); + expect(firstPollUserAgent).toEqual(value); + expect(deleteUserAgent).toEqual(value); + expect(secondPollUserAgent).toEqual(value); + }); + }); }); function makeClosedPromise(transport: LongPollingTransport): Promise<void> { diff --git a/src/SignalR/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts b/src/SignalR/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts index bad6a9fb3a..9fb038fa0f 100644 --- a/src/SignalR/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts +++ b/src/SignalR/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts @@ -6,6 +6,7 @@ import { TransferFormat } from "../src/ITransport"; import { HttpClient, HttpRequest } from "../src/HttpClient"; import { ILogger } from "../src/ILogger"; import { ServerSentEventsTransport } from "../src/ServerSentEventsTransport"; +import { getUserAgentHeader } from "../src/Utils"; import { VerifyLogger } from "./Common"; import { TestEventSource, TestMessageEvent } from "./TestEventSource"; import { TestHttpClient } from "./TestHttpClient"; @@ -16,7 +17,7 @@ registerUnhandledRejectionHandler(); describe("ServerSentEventsTransport", () => { it("does not allow non-text formats", async () => { await VerifyLogger.run(async (logger) => { - const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource); + const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource, true); await expect(sse.connect("", TransferFormat.Binary)) .rejects @@ -26,7 +27,7 @@ describe("ServerSentEventsTransport", () => { it("connect waits for EventSource to be connected", async () => { await VerifyLogger.run(async (logger) => { - const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource); + const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource, true); let connectComplete: boolean = false; const connectPromise = (async () => { @@ -47,7 +48,7 @@ describe("ServerSentEventsTransport", () => { it("connect failure does not call onclose handler", async () => { await VerifyLogger.run(async (logger) => { - const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource); + const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource, true); let closeCalled = false; sse.onclose = () => closeCalled = true; @@ -168,7 +169,7 @@ describe("ServerSentEventsTransport", () => { it("send throws if not connected", async () => { await VerifyLogger.run(async (logger) => { - const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource); + const sse = new ServerSentEventsTransport(new TestHttpClient(), undefined, logger, true, TestEventSource, true); await expect(sse.send("")) .rejects @@ -200,10 +201,30 @@ describe("ServerSentEventsTransport", () => { expect(error).toEqual(new Error("error parsing")); }); }); + + it("sets user agent header on connect and sends", async () => { + await VerifyLogger.run(async (logger) => { + let request: HttpRequest; + const httpClient = new TestHttpClient().on((r) => { + request = r; + return ""; + }); + + const sse = await createAndStartSSE(logger, "http://example.com", undefined, httpClient); + + let [, value] = getUserAgentHeader(); + expect((TestEventSource.eventSource.eventSourceInitDict as any).headers[`User-Agent`]).toEqual(value); + await sse.send(""); + + [, value] = getUserAgentHeader(); + expect(request!.headers![`User-Agent`]).toBe(value); + expect(request!.url).toBe("http://example.com"); + }); + }); }); async function createAndStartSSE(logger: ILogger, url?: string, accessTokenFactory?: (() => string | Promise<string>), httpClient?: HttpClient): Promise<ServerSentEventsTransport> { - const sse = new ServerSentEventsTransport(httpClient || new TestHttpClient(), accessTokenFactory, logger, true, TestEventSource); + const sse = new ServerSentEventsTransport(httpClient || new TestHttpClient(), accessTokenFactory, logger, true, TestEventSource, true); const connectPromise = sse.connect(url || "http://example.com", TransferFormat.Text); await TestEventSource.eventSource.openSet; diff --git a/src/SignalR/clients/ts/signalr/tests/TestConnection.ts b/src/SignalR/clients/ts/signalr/tests/TestConnection.ts index 0ad7d89a95..e4f35281eb 100644 --- a/src/SignalR/clients/ts/signalr/tests/TestConnection.ts +++ b/src/SignalR/clients/ts/signalr/tests/TestConnection.ts @@ -17,13 +17,14 @@ export class TestConnection implements IConnection { private autoHandshake: boolean | null; - constructor(autoHandshake: boolean = true) { + constructor(autoHandshake: boolean = true, hasInherentKeepAlive: boolean = false) { this.onreceive = null; this.onclose = null; this.sentData = []; this.lastInvocationId = null; this.autoHandshake = autoHandshake; this.baseUrl = "http://example.com"; + this.features.inherentKeepAlive = hasInherentKeepAlive; } public start(): Promise<void> { diff --git a/src/SignalR/clients/ts/signalr/tests/TestEventSource.ts b/src/SignalR/clients/ts/signalr/tests/TestEventSource.ts index d77f350616..49b63afe40 100644 --- a/src/SignalR/clients/ts/signalr/tests/TestEventSource.ts +++ b/src/SignalR/clients/ts/signalr/tests/TestEventSource.ts @@ -11,6 +11,7 @@ export class TestEventSource { public onmessage!: (evt: MessageEvent) => any; public readyState: number = 0; public url: string = ""; + public eventSourceInitDict?: EventSourceInit; public withCredentials: boolean = false; // tslint:disable-next-line:variable-name @@ -31,6 +32,7 @@ export class TestEventSource { constructor(url: string, eventSourceInitDict?: EventSourceInit) { this.url = url; + this.eventSourceInitDict = eventSourceInitDict; TestEventSource.eventSource = this; diff --git a/src/SignalR/clients/ts/signalr/tests/TestWebSocket.ts b/src/SignalR/clients/ts/signalr/tests/TestWebSocket.ts index 1eaf631d5d..a7e0ac6dd9 100644 --- a/src/SignalR/clients/ts/signalr/tests/TestWebSocket.ts +++ b/src/SignalR/clients/ts/signalr/tests/TestWebSocket.ts @@ -12,6 +12,7 @@ export class TestWebSocket { public protocol: string; public readyState: number = 1; public url: string; + public options?: any; public static webSocketSet: PromiseSource; public static webSocket: TestWebSocket; @@ -67,10 +68,11 @@ export class TestWebSocket { throw new Error("Method not implemented."); } - constructor(url: string, protocols?: string | string[]) { + constructor(url: string, protocols?: string | string[], options?: any) { this.url = url; this.protocol = protocols ? (typeof protocols === "string" ? protocols : protocols[0]) : ""; this.receivedData = []; + this.options = options; TestWebSocket.webSocket = this; diff --git a/src/SignalR/clients/ts/signalr/tests/UserAgent.test.ts b/src/SignalR/clients/ts/signalr/tests/UserAgent.test.ts new file mode 100644 index 0000000000..f1e26f0d88 --- /dev/null +++ b/src/SignalR/clients/ts/signalr/tests/UserAgent.test.ts @@ -0,0 +1,17 @@ +// 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. + +import { constructUserAgent } from "../src/Utils"; + +describe("User Agent", () => { + [["1.0.4-build.10", "Linux", "NodeJS", "10", "Microsoft SignalR/1.0 (1.0.4-build.10; Linux; NodeJS; 10)"], + ["1.4.7-build.10", "", "Browser", "", "Microsoft SignalR/1.4 (1.4.7-build.10; Unknown OS; Browser; Unknown Runtime Version)"], + ["3.1.1-build.10", "macOS", "Browser", "", "Microsoft SignalR/3.1 (3.1.1-build.10; macOS; Browser; Unknown Runtime Version)"], + ["3.1.3-build.10", "", "Browser", "4", "Microsoft SignalR/3.1 (3.1.3-build.10; Unknown OS; Browser; 4)"]] + .forEach(([version, os, runtime, runtimeVersion, expected]) => { + it(`is in correct format`, async () => { + const userAgent = constructUserAgent(version, os, runtime, runtimeVersion); + expect(userAgent).toBe(expected); + }); + }); +}); diff --git a/src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts b/src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts index e26eaa86a3..cb4455a517 100644 --- a/src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts +++ b/src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts @@ -3,6 +3,7 @@ import { ILogger } from "../src/ILogger"; import { TransferFormat } from "../src/ITransport"; +import { getUserAgentHeader } from "../src/Utils"; import { WebSocketTransport } from "../src/WebSocketTransport"; import { VerifyLogger } from "./Common"; import { TestMessageEvent } from "./TestEventSource"; @@ -229,6 +230,92 @@ describe("WebSocketTransport", () => { }); }); }); + + it("sets user agent header on connect", async () => { + await VerifyLogger.run(async (logger) => { + (global as any).ErrorEvent = TestEvent; + const webSocket = await createAndStartWebSocket(logger); + + let closeCalled: boolean = false; + let error: Error; + webSocket.onclose = (e) => { + closeCalled = true; + error = e!; + }; + + const [, value] = getUserAgentHeader(); + expect(TestWebSocket.webSocket.options!.headers[`User-Agent`]).toEqual(value); + + await webSocket.stop(); + + expect(closeCalled).toBe(true); + expect(error!).toBeUndefined(); + + await expect(webSocket.send("")) + .rejects + .toBe("WebSocket is not in the OPEN state"); + }); + }); + + it("is closed from 'onreceive' callback throwing", async () => { + await VerifyLogger.run(async (logger) => { + (global as any).ErrorEvent = TestEvent; + const webSocket = await createAndStartWebSocket(logger); + + let closeCalled: boolean = false; + let error: Error; + webSocket.onclose = (e) => { + closeCalled = true; + error = e!; + }; + + const receiveError = new Error("callback error"); + webSocket.onreceive = (data) => { + throw receiveError; + }; + + const message = new TestMessageEvent(); + message.data = "receive data"; + TestWebSocket.webSocket.onmessage(message); + + expect(closeCalled).toBe(true); + expect(error!).toBe(receiveError); + + await expect(webSocket.send("")) + .rejects + .toBe("WebSocket is not in the OPEN state"); + }); + }); + + it("does not run onclose callback if Transport does not fully connect and exits", async () => { + await VerifyLogger.run(async (logger) => { + (global as any).ErrorEvent = TestErrorEvent; + const webSocket = new WebSocketTransport(new TestHttpClient(), undefined, logger, true, TestWebSocket); + + const connectPromise = webSocket.connect("http://example.com", TransferFormat.Text); + + await TestWebSocket.webSocket.closeSet; + + let closeCalled: boolean = false; + let error: Error; + webSocket.onclose = (e) => { + closeCalled = true; + error = e!; + }; + + const message = new TestCloseEvent(); + message.wasClean = false; + message.code = 1; + message.reason = "just cause"; + TestWebSocket.webSocket.onclose(message); + + expect(closeCalled).toBe(false); + expect(error!).toBeUndefined(); + + TestWebSocket.webSocket.onerror(new TestEvent()); + await expect(connectPromise).rejects.toThrow("There was an error with the transport."); + }); + }); }); async function createAndStartWebSocket(logger: ILogger, url?: string, accessTokenFactory?: (() => string | Promise<string>), format?: TransferFormat): Promise<WebSocketTransport> { diff --git a/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netcoreapp.cs b/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netcoreapp.cs index f557b74f58..d5d38749c7 100644 --- a/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netcoreapp.cs +++ b/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netcoreapp.cs @@ -6,8 +6,8 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class AvailableTransport { public AvailableTransport() { } - public System.Collections.Generic.IList<string> TransferFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList<string> TransferFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class HttpTransports { @@ -31,12 +31,12 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class NegotiationResponse { public NegotiationResponse() { } - public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<Microsoft.AspNetCore.Http.Connections.AvailableTransport> AvailableTransports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ConnectionToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<Microsoft.AspNetCore.Http.Connections.AvailableTransport> AvailableTransports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ConnectionToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netstandard2.0.cs b/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netstandard2.0.cs index f557b74f58..d5d38749c7 100644 --- a/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netstandard2.0.cs +++ b/src/SignalR/common/Http.Connections.Common/ref/Microsoft.AspNetCore.Http.Connections.Common.netstandard2.0.cs @@ -6,8 +6,8 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class AvailableTransport { public AvailableTransport() { } - public System.Collections.Generic.IList<string> TransferFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Collections.Generic.IList<string> TransferFormats { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Transport { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public static partial class HttpTransports { @@ -31,12 +31,12 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class NegotiationResponse { public NegotiationResponse() { } - public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<Microsoft.AspNetCore.Http.Connections.AvailableTransport> AvailableTransports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string ConnectionToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string AccessToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<Microsoft.AspNetCore.Http.Connections.AvailableTransport> AvailableTransports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string ConnectionToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string Url { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } diff --git a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj index 521467f849..c40fa68e6d 100644 --- a/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj +++ b/src/SignalR/common/Http.Connections.Common/src/Microsoft.AspNetCore.Http.Connections.Common.csproj @@ -24,7 +24,7 @@ <Reference Include="System.Text.Json" /> </ItemGroup> - <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '3.1'"> + <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '5.0'"> <!-- This dependency was replaced by System.Text.Json between 3.0 and 2.2. This suppression can be removed after 3.0 is complete. --> <SuppressBaselineReference Include="Newtonsoft.Json" /> diff --git a/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs b/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs index a98e0ba94c..ae69b56cdd 100644 --- a/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs +++ b/src/SignalR/common/Http.Connections.Common/src/NegotiateProtocol.cs @@ -264,13 +264,11 @@ namespace Microsoft.AspNetCore.Http.Connections switch (reader.TokenType) { case JsonTokenType.PropertyName: - var memberName = reader.ValueSpan; - - if (memberName.SequenceEqual(TransportPropertyNameBytes.EncodedUtf8Bytes)) + if (reader.ValueTextEquals(TransportPropertyNameBytes.EncodedUtf8Bytes)) { availableTransport.Transport = reader.ReadAsString(TransportPropertyName); } - else if (memberName.SequenceEqual(TransferFormatsPropertyNameBytes.EncodedUtf8Bytes)) + else if (reader.ValueTextEquals(TransferFormatsPropertyNameBytes.EncodedUtf8Bytes)) { reader.CheckRead(); reader.EnsureArrayStart(); diff --git a/src/SignalR/common/Http.Connections/ref/Microsoft.AspNetCore.Http.Connections.netcoreapp.cs b/src/SignalR/common/Http.Connections/ref/Microsoft.AspNetCore.Http.Connections.netcoreapp.cs index 5ee369727c..9f70e9da9c 100644 --- a/src/SignalR/common/Http.Connections/ref/Microsoft.AspNetCore.Http.Connections.netcoreapp.cs +++ b/src/SignalR/common/Http.Connections/ref/Microsoft.AspNetCore.Http.Connections.netcoreapp.cs @@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class ConnectionOptions { public ConnectionOptions() { } - public System.TimeSpan? DisconnectTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan? DisconnectTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class ConnectionOptionsSetup : Microsoft.Extensions.Options.IConfigureOptions<Microsoft.AspNetCore.Http.Connections.ConnectionOptions> { @@ -50,18 +50,18 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class HttpConnectionDispatcherOptions { public HttpConnectionDispatcherOptions() { } - public long ApplicationMaxBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<Microsoft.AspNetCore.Authorization.IAuthorizeData> AuthorizationData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Http.Connections.LongPollingOptions LongPolling { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int MinimumProtocolVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long TransportMaxBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public Microsoft.AspNetCore.Http.Connections.WebSocketOptions WebSockets { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public long ApplicationMaxBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<Microsoft.AspNetCore.Authorization.IAuthorizeData> AuthorizationData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public Microsoft.AspNetCore.Http.Connections.LongPollingOptions LongPolling { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int MinimumProtocolVersion { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long TransportMaxBufferSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Connections.HttpTransportType Transports { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public Microsoft.AspNetCore.Http.Connections.WebSocketOptions WebSockets { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class LongPollingOptions { public LongPollingOptions() { } - public System.TimeSpan PollTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan PollTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class NegotiateMetadata { @@ -70,8 +70,8 @@ namespace Microsoft.AspNetCore.Http.Connections public partial class WebSocketOptions { public WebSocketOptions() { } - public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<System.Collections.Generic.IList<string>, string> SubProtocolSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan CloseTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<System.Collections.Generic.IList<string>, string> SubProtocolSelector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.Http.Connections.Features diff --git a/src/SignalR/common/Http.Connections/test/NegotiateProtocolTests.cs b/src/SignalR/common/Http.Connections/test/NegotiateProtocolTests.cs index 704f0f4d27..00d803ffdd 100644 --- a/src/SignalR/common/Http.Connections/test/NegotiateProtocolTests.cs +++ b/src/SignalR/common/Http.Connections/test/NegotiateProtocolTests.cs @@ -18,6 +18,8 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests [InlineData("{\"url\": \"http://foo.com/chat\"}", null, null, "http://foo.com/chat", null, 0, null)] [InlineData("{\"url\": \"http://foo.com/chat\", \"accessToken\": \"token\"}", null, null, "http://foo.com/chat", "token", 0, null)] [InlineData("{\"connectionId\":\"123\",\"availableTransports\":[{\"transport\":\"test\",\"transferFormats\":[]}]}", "123", new[] { "test" }, null, null, 0, null)] + [InlineData("{\"connectionId\":\"123\",\"availableTransports\":[{\"\\u0074ransport\":\"test\",\"transferFormats\":[]}]}", "123", new[] { "test" }, null, null, 0, null)] + [InlineData("{\"negotiateVersion\":123,\"connectionId\":\"123\",\"connectionToken\":\"789\",\"availableTransports\":[{\"\\u0074ransport\":\"test\",\"transferFormats\":[]}]}", "123", new[] { "test" }, null, null, 123, "789")] [InlineData("{\"negotiateVersion\":123,\"negotiateVersion\":321, \"connectionToken\":\"789\",\"connectionId\":\"123\",\"availableTransports\":[]}", "123", new string[0], null, null, 321, "789")] [InlineData("{\"ignore\":123,\"negotiateVersion\":123, \"connectionToken\":\"789\",\"connectionId\":\"123\",\"availableTransports\":[]}", "123", new string[0], null, null, 123, "789")] [InlineData("{\"connectionId\":\"123\",\"availableTransports\":[],\"negotiateVersion\":123, \"connectionToken\":\"789\"}", "123", new string[0], null, null, 123, "789")] diff --git a/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netcoreapp.cs b/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netcoreapp.cs index 28b4ec1d30..7cab28e40b 100644 --- a/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netcoreapp.cs +++ b/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netcoreapp.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.SignalR public partial class JsonHubProtocolOptions { public JsonHubProtocolOptions() { } - public System.Text.Json.JsonSerializerOptions PayloadSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Text.Json.JsonSerializerOptions PayloadSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.SignalR.Protocol diff --git a/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netstandard2.0.cs b/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netstandard2.0.cs index 28b4ec1d30..7cab28e40b 100644 --- a/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netstandard2.0.cs +++ b/src/SignalR/common/Protocols.Json/ref/Microsoft.AspNetCore.SignalR.Protocols.Json.netstandard2.0.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.SignalR public partial class JsonHubProtocolOptions { public JsonHubProtocolOptions() { } - public System.Text.Json.JsonSerializerOptions PayloadSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.Text.Json.JsonSerializerOptions PayloadSerializerOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.SignalR.Protocol diff --git a/src/SignalR/common/Protocols.Json/src/JsonHubProtocolOptions.cs b/src/SignalR/common/Protocols.Json/src/JsonHubProtocolOptions.cs index 1164497f9a..46f5003a78 100644 --- a/src/SignalR/common/Protocols.Json/src/JsonHubProtocolOptions.cs +++ b/src/SignalR/common/Protocols.Json/src/JsonHubProtocolOptions.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.SignalR.Protocol; namespace Microsoft.AspNetCore.SignalR { /// <summary> - /// Options used to configure a <see cref="JsonHubProtocolOptions"/> instance. + /// Options used to configure a <see cref="JsonHubProtocol"/> instance. /// </summary> public class JsonHubProtocolOptions { diff --git a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj index 27ac41a9df..2dd22c44a5 100644 --- a/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj +++ b/src/SignalR/common/Protocols.Json/src/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj @@ -23,7 +23,7 @@ <Reference Include="Microsoft.AspNetCore.SignalR.Common" /> </ItemGroup> - <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '3.1'"> + <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '5.0'"> <!-- This dependency was replaced by System.Text.Json between 3.0 and 2.2. This suppression can be removed after 3.0 is complete. --> <SuppressBaselineReference Include="Newtonsoft.Json" /> </ItemGroup> diff --git a/src/SignalR/common/Protocols.Json/src/Protocol/JsonHubProtocol.cs b/src/SignalR/common/Protocols.Json/src/Protocol/JsonHubProtocol.cs index a5696467bf..0fb09e77df 100644 --- a/src/SignalR/common/Protocols.Json/src/Protocol/JsonHubProtocol.cs +++ b/src/SignalR/common/Protocols.Json/src/Protocol/JsonHubProtocol.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.ExceptionServices; +using System.Text.Encodings.Web; using System.Text.Json; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Internal; @@ -563,19 +564,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol writer.WriteStartArray(ArgumentsPropertyNameBytes); foreach (var argument in arguments) { - var type = argument?.GetType(); - if (type == typeof(DateTime)) - { - writer.WriteStringValue((DateTime)argument); - } - else if (type == typeof(DateTimeOffset)) - { - writer.WriteStringValue((DateTimeOffset)argument); - } - else - { - JsonSerializer.Serialize(writer, argument, type, _payloadSerializerOptions); - } + JsonSerializer.Serialize(writer, argument, argument?.GetType(), _payloadSerializerOptions); } writer.WriteEndArray(); } @@ -757,19 +746,20 @@ namespace Microsoft.AspNetCore.SignalR.Protocol internal static JsonSerializerOptions CreateDefaultSerializerSettings() { - var options = new JsonSerializerOptions(); - options.WriteIndented = false; - options.ReadCommentHandling = JsonCommentHandling.Disallow; - options.AllowTrailingCommas = false; - options.IgnoreNullValues = false; - options.IgnoreReadOnlyProperties = false; - options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - options.PropertyNameCaseInsensitive = true; - options.MaxDepth = 64; - options.DictionaryKeyPolicy = null; - options.DefaultBufferSize = 16 * 1024; - - return options; + return new JsonSerializerOptions() + { + WriteIndented = false, + ReadCommentHandling = JsonCommentHandling.Disallow, + AllowTrailingCommas = false, + IgnoreNullValues = false, + IgnoreReadOnlyProperties = false, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNameCaseInsensitive = true, + MaxDepth = 64, + DictionaryKeyPolicy = null, + DefaultBufferSize = 16 * 1024, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + }; } } } diff --git a/src/SignalR/common/Protocols.NewtonsoftJson/ref/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.netstandard2.0.cs b/src/SignalR/common/Protocols.NewtonsoftJson/ref/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.netstandard2.0.cs index e04928abf7..61558ba6cb 100644 --- a/src/SignalR/common/Protocols.NewtonsoftJson/ref/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.netstandard2.0.cs +++ b/src/SignalR/common/Protocols.NewtonsoftJson/ref/Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson.netstandard2.0.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.SignalR public partial class NewtonsoftJsonHubProtocolOptions { public NewtonsoftJsonHubProtocolOptions() { } - public Newtonsoft.Json.JsonSerializerSettings PayloadSerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public Newtonsoft.Json.JsonSerializerSettings PayloadSerializerSettings { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.AspNetCore.SignalR.Protocol @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public NewtonsoftJsonHubProtocol() { } public NewtonsoftJsonHubProtocol(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.SignalR.NewtonsoftJsonHubProtocolOptions> options) { } public string Name { get { throw null; } } - public Newtonsoft.Json.JsonSerializer PayloadSerializer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Newtonsoft.Json.JsonSerializer PayloadSerializer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Connections.TransferFormat TransferFormat { get { throw null; } } public int Version { get { throw null; } } public System.ReadOnlyMemory<byte> GetMessageBytes(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) { throw null; } diff --git a/src/SignalR/common/Shared/ReusableUtf8JsonWriter.cs b/src/SignalR/common/Shared/ReusableUtf8JsonWriter.cs index 1dc980d750..c05c0397e6 100644 --- a/src/SignalR/common/Shared/ReusableUtf8JsonWriter.cs +++ b/src/SignalR/common/Shared/ReusableUtf8JsonWriter.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Text.Encodings.Web; using System.Text.Json; namespace Microsoft.AspNetCore.Internal @@ -20,7 +21,13 @@ namespace Microsoft.AspNetCore.Internal public ReusableUtf8JsonWriter(IBufferWriter<byte> stream) { - _writer = new Utf8JsonWriter(stream, new JsonWriterOptions() { SkipValidation = true }); + _writer = new Utf8JsonWriter(stream, new JsonWriterOptions() + { +#if !DEBUG + SkipValidation = true, +#endif + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }); } public static ReusableUtf8JsonWriter Get(IBufferWriter<byte> stream) diff --git a/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netcoreapp.cs b/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netcoreapp.cs index 7b8c7751c8..7a0c3b3617 100644 --- a/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netcoreapp.cs +++ b/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netcoreapp.cs @@ -32,15 +32,15 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public static readonly Microsoft.AspNetCore.SignalR.Protocol.CloseMessage Empty; public CloseMessage(string error) { } public CloseMessage(string error, bool allowReconnect) { } - public bool AllowReconnect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AllowReconnect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class CompletionMessage : Microsoft.AspNetCore.SignalR.Protocol.HubInvocationMessage { public CompletionMessage(string invocationId, string error, object result, bool hasResult) : base (default(string)) { } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool HasResult { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool HasResult { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage Empty(string invocationId) { throw null; } public override string ToString() { throw null; } public static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage WithError(string invocationId, string error) { throw null; } @@ -57,20 +57,20 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class HandshakeRequestMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { public HandshakeRequestMessage(string protocol, int version) { } - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class HandshakeResponseMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { public static readonly Microsoft.AspNetCore.SignalR.Protocol.HandshakeResponseMessage Empty; public HandshakeResponseMessage(string error) { } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class HubInvocationMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { protected HubInvocationMessage(string invocationId) { } - public System.Collections.Generic.IDictionary<string, string> Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string InvocationId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary<string, string> Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string InvocationId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class HubMessage { @@ -80,9 +80,9 @@ namespace Microsoft.AspNetCore.SignalR.Protocol { protected HubMethodInvocationMessage(string invocationId, string target, object[] arguments) : base (default(string)) { } protected HubMethodInvocationMessage(string invocationId, string target, object[] arguments, string[] streamIds) : base (default(string)) { } - public object[] Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string[] StreamIds { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object[] Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string[] StreamIds { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class HubProtocolConstants { @@ -111,8 +111,8 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class InvocationBindingFailureMessage : Microsoft.AspNetCore.SignalR.Protocol.HubInvocationMessage { public InvocationBindingFailureMessage(string invocationId, string target, System.Runtime.ExceptionServices.ExceptionDispatchInfo bindingFailure) : base (default(string)) { } - public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class InvocationMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage { @@ -129,8 +129,8 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class StreamBindingFailureMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { public StreamBindingFailureMessage(string id, System.Runtime.ExceptionServices.ExceptionDispatchInfo bindingFailure) { } - public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class StreamInvocationMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage { @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class StreamItemMessage : Microsoft.AspNetCore.SignalR.Protocol.HubInvocationMessage { public StreamItemMessage(string invocationId, object item) : base (default(string)) { } - public object Item { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Item { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string ToString() { throw null; } } } diff --git a/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netstandard2.0.cs b/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netstandard2.0.cs index 7b8c7751c8..7a0c3b3617 100644 --- a/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netstandard2.0.cs +++ b/src/SignalR/common/SignalR.Common/ref/Microsoft.AspNetCore.SignalR.Common.netstandard2.0.cs @@ -32,15 +32,15 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public static readonly Microsoft.AspNetCore.SignalR.Protocol.CloseMessage Empty; public CloseMessage(string error) { } public CloseMessage(string error, bool allowReconnect) { } - public bool AllowReconnect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public bool AllowReconnect { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class CompletionMessage : Microsoft.AspNetCore.SignalR.Protocol.HubInvocationMessage { public CompletionMessage(string invocationId, string error, object result, bool hasResult) : base (default(string)) { } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public bool HasResult { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public object Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public bool HasResult { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public object Result { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage Empty(string invocationId) { throw null; } public override string ToString() { throw null; } public static Microsoft.AspNetCore.SignalR.Protocol.CompletionMessage WithError(string invocationId, string error) { throw null; } @@ -57,20 +57,20 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class HandshakeRequestMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { public HandshakeRequestMessage(string protocol, int version) { } - public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public int Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class HandshakeResponseMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { public static readonly Microsoft.AspNetCore.SignalR.Protocol.HandshakeResponseMessage Empty; public HandshakeResponseMessage(string error) { } - public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Error { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class HubInvocationMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { protected HubInvocationMessage(string invocationId) { } - public System.Collections.Generic.IDictionary<string, string> Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public string InvocationId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Collections.Generic.IDictionary<string, string> Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public string InvocationId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class HubMessage { @@ -80,9 +80,9 @@ namespace Microsoft.AspNetCore.SignalR.Protocol { protected HubMethodInvocationMessage(string invocationId, string target, object[] arguments) : base (default(string)) { } protected HubMethodInvocationMessage(string invocationId, string target, object[] arguments, string[] streamIds) : base (default(string)) { } - public object[] Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string[] StreamIds { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object[] Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string[] StreamIds { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class HubProtocolConstants { @@ -111,8 +111,8 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class InvocationBindingFailureMessage : Microsoft.AspNetCore.SignalR.Protocol.HubInvocationMessage { public InvocationBindingFailureMessage(string invocationId, string target, System.Runtime.ExceptionServices.ExceptionDispatchInfo bindingFailure) : base (default(string)) { } - public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Target { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class InvocationMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage { @@ -129,8 +129,8 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class StreamBindingFailureMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMessage { public StreamBindingFailureMessage(string id, System.Runtime.ExceptionServices.ExceptionDispatchInfo bindingFailure) { } - public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Runtime.ExceptionServices.ExceptionDispatchInfo BindingFailure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string Id { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class StreamInvocationMessage : Microsoft.AspNetCore.SignalR.Protocol.HubMethodInvocationMessage { @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol public partial class StreamItemMessage : Microsoft.AspNetCore.SignalR.Protocol.HubInvocationMessage { public StreamItemMessage(string invocationId, object item) : base (default(string)) { } - public object Item { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public object Item { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public override string ToString() { throw null; } } } diff --git a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj index fa97b3e082..eab77e2bf1 100644 --- a/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj +++ b/src/SignalR/common/SignalR.Common/src/Microsoft.AspNetCore.SignalR.Common.csproj @@ -29,7 +29,7 @@ <Reference Include="System.Text.Json" /> </ItemGroup> - <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '3.1'"> + <ItemGroup Condition="'$(AspNetCoreMajorMinorVersion)' == '5.0'"> <!-- This dependency was replaced by System.Text.Json between 3.0 and 2.2. This suppression can be removed after 3.0 is complete. --> <SuppressBaselineReference Include="Newtonsoft.Json" /> diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Formatters/BinaryMessageParserTests.cs b/src/SignalR/common/SignalR.Common/test/Internal/Formatters/BinaryMessageParserTests.cs index c2f02811e7..8cd0170c9f 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Formatters/BinaryMessageParserTests.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Formatters/BinaryMessageParserTests.cs @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Formatters { var ex = Assert.Throws<FormatException>(() => { - var buffer = new ReadOnlySequence<byte>(payload);; + var buffer = new ReadOnlySequence<byte>(payload); BinaryMessageParser.TryParseMessage(ref buffer, out var message); }); Assert.Equal("Messages over 2GB in size are not supported.", ex.Message); diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/HandshakeProtocolTests.cs b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/HandshakeProtocolTests.cs index 27560c502a..9a88d32a57 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/HandshakeProtocolTests.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/HandshakeProtocolTests.cs @@ -15,6 +15,12 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol [InlineData("{\"protocol\":\"dummy\",\"version\":1}\u001e", "dummy", 1)] [InlineData("{\"protocol\":\"\",\"version\":10}\u001e", "", 10)] [InlineData("{\"protocol\":\"\",\"version\":10,\"unknown\":null}\u001e", "", 10)] + [InlineData("{\"protocol\":\"firstProtocol\",\"protocol\":\"secondProtocol\",\"version\":1}\u001e", "secondProtocol", 1)] + [InlineData("{\"protocol\":\"firstProtocol\",\"protocol\":\"secondProtocol\",\"version\":1,\"version\":75}\u001e", "secondProtocol", 75)] + [InlineData("{\"protocol\":\"dummy\",\"version\":1,\"ignoredField\":99}\u001e", "dummy", 1)] + [InlineData("{\"protocol\":\"dummy\",\"version\":1}{\"protocol\":\"wrong\",\"version\":99}\u001e", "dummy", 1)] + [InlineData("{\"protocol\":\"\\u0064ummy\",\"version\":1}\u001e", "dummy", 1)] + [InlineData("{\"\\u0070rotoco\\u006c\":\"\\u0064ummy\",\"version\":1}\u001e", "dummy", 1)] public void ParsingHandshakeRequestMessageSuccessForValidMessages(string json, string protocol, int version) { var message = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(json)); diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTests.cs b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTests.cs index a2f696ab17..6f9ba5cb60 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTests.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTests.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using System.Text.Encodings.Web; using System.Text.Json; using Microsoft.AspNetCore.Internal; using Microsoft.AspNetCore.SignalR.Protocol; @@ -28,7 +29,8 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol PayloadSerializerOptions = new JsonSerializerOptions() { IgnoreNullValues = ignoreNullValues, - PropertyNamingPolicy = useCamelCase ? JsonNamingPolicy.CamelCase : null + PropertyNamingPolicy = useCamelCase ? JsonNamingPolicy.CamelCase : null, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, } }; @@ -39,6 +41,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol [InlineData("", "Error reading JSON.")] [InlineData("42", "Unexpected JSON Token Type 'Number'. Expected a JSON Object.")] [InlineData("{\"type\":\"foo\"}", "Expected 'type' to be of type Number.")] + [InlineData("{\"type\":3,\"invocationId\":\"42\",\"result\":true", "Error reading JSON.")] public void CustomInvalidMessages(string input, string expectedMessage) { input = Frame(input); @@ -101,98 +104,18 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol Assert.Equal(expectedMessage, message); } - [Fact] - public void ReadCaseInsensitivePropertiesByDefault() - { - var input = Frame("{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StrIngProp\":\"test\",\"DoublePrOp\":3.14159,\"IntProp\":43,\"DateTimeProp\":\"2019-06-03T22:00:00\",\"NuLLProp\":null,\"ByteARRProp\":\"AgQG\"}}"); - - var binder = new TestBinder(null, typeof(TemporaryCustomObject)); - var data = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(input)); - JsonHubProtocol.TryParseMessage(ref data, binder, out var message); - - var streamItemMessage = Assert.IsType<StreamItemMessage>(message); - Assert.Equal(new TemporaryCustomObject() - { - ByteArrProp = new byte[] { 2, 4, 6 }, - IntProp = 43, - DoubleProp = 3.14159, - StringProp = "test", - DateTimeProp = DateTime.Parse("6/3/2019 10:00:00 PM") - }, streamItemMessage.Item); - } - public static IDictionary<string, JsonProtocolTestData> CustomProtocolTestData => new[] { new JsonProtocolTestData("InvocationMessage_HasFloatArgument", new InvocationMessage(null, "Target", new object[] { 1, "Foo", 2.0f }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[1,\"Foo\",2]}"), - new JsonProtocolTestData("InvocationMessage_StringIsoDateArgument", new InvocationMessage("Method", new object[] { "2016-05-10T13:51:20+12:34" }), true, true, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"2016-05-10T13:51:20\\u002B12:34\"]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNoCamelCase", new InvocationMessage(null, "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), false, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnore", new InvocationMessage(null, "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new InvocationMessage(null, "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), false, false, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueInclude", new InvocationMessage(null, "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), true, false, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), new JsonProtocolTestData("InvocationMessage_HasHeaders", AddHeaders(TestHeaders, new InvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f })), true, true, "{\"type\":1," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2]}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNoCamelCase", new StreamItemMessage("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), false, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueIgnore", new StreamItemMessage("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueIgnoreAndNoCamelCase", new StreamItemMessage("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), false, false, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueInclude", new StreamItemMessage("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), true, false, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), new JsonProtocolTestData("StreamItemMessage_HasFloatItem", new StreamItemMessage("123", 2.0f), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":2}"), - new JsonProtocolTestData("StreamItemMessage_HasHeaders", AddHeaders(TestHeaders, new StreamItemMessage("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } })), true, false, "{\"type\":2," + SerializedHeaders + ",\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), new JsonProtocolTestData("CompletionMessage_HasFloatResult", CompletionMessage.WithResult("123", 2.0f), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":2}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNoCamelCase", CompletionMessage.WithResult("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), false, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueIgnore", CompletionMessage.WithResult("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueIncludeAndNoCamelCase", CompletionMessage.WithResult("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), false, false, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueInclude", CompletionMessage.WithResult("123", new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } }), true, false, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasErrorAndCamelCase", CompletionMessage.Empty("123"), true, true, "{\"type\":3,\"invocationId\":\"123\"}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNoCamelCase", new StreamInvocationMessage("123", "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), false, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueIgnore", new StreamInvocationMessage("123", "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new StreamInvocationMessage("123", "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), false, false, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueInclude", new StreamInvocationMessage("123", "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } }), true, false, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), new JsonProtocolTestData("StreamInvocationMessage_HasFloatArgument", new StreamInvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasHeaders", AddHeaders(TestHeaders, new StreamInvocationMessage("123", "Target", new object[] { new TemporaryCustomObject() { ByteArrProp = new byte[] { 1, 2, 3 } } })), true, false, "{\"type\":4," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), }.ToDictionary(t => t.Name); public static IEnumerable<object[]> CustomProtocolTestDataNames => CustomProtocolTestData.Keys.Select(name => new object[] { name }); } - - // Revert back to CustomObject when initial values on arrays are supported - // e.g. byte[] arr { get; set; } = byte[] { 1, 2, 3 }; - internal class TemporaryCustomObject : IEquatable<TemporaryCustomObject> - { - // Not intended to be a full set of things, just a smattering of sample serializations - public string StringProp { get; set; } = "SignalR!"; - - public double DoubleProp { get; set; } = 6.2831853071; - - public int IntProp { get; set; } = 42; - - public DateTime DateTimeProp { get; set; } = new DateTime(2017, 4, 11, 0, 0, 0, DateTimeKind.Utc); - - public object NullProp { get; set; } = null; - - public byte[] ByteArrProp { get; set; } - - public override bool Equals(object obj) - { - return obj is TemporaryCustomObject o && Equals(o); - } - - public override int GetHashCode() - { - // This is never used in a hash table - return 0; - } - - public bool Equals(TemporaryCustomObject right) - { - // This allows the comparer below to properly compare the object in the test. - return string.Equals(StringProp, right.StringProp, StringComparison.Ordinal) && - DoubleProp == right.DoubleProp && - IntProp == right.IntProp && - DateTime.Equals(DateTimeProp, right.DateTimeProp) && - NullProp == right.NullProp && - System.Linq.Enumerable.SequenceEqual(ByteArrProp, right.ByteArrProp); - } - } } diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTestsBase.cs b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTestsBase.cs index 6134d51f16..0465959d1a 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTestsBase.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/JsonHubProtocolTestsBase.cs @@ -40,12 +40,30 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol new JsonProtocolTestData("InvocationMessage_HasStreamAndNormalArgument", new InvocationMessage(null, "Target", new object[] { 42 }, new string[] { "__test_id__" }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[42],\"streamIds\":[\"__test_id__\"]}"), new JsonProtocolTestData("InvocationMessage_HasMultipleStreams", new InvocationMessage(null, "Target", Array.Empty<object>(), new string[] { "__test_id__", "__test_id2__" }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[],\"streamIds\":[\"__test_id__\",\"__test_id2__\"]}"), new JsonProtocolTestData("InvocationMessage_DateTimeOffsetArgument", new InvocationMessage("Method", new object[] { DateTimeOffset.Parse("2016-05-10T13:51:20+12:34") }), true, true, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"2016-05-10T13:51:20+12:34\"]}"), + new JsonProtocolTestData("InvocationMessage_StringIsoDateArgument", new InvocationMessage("Method", new object[] { "2016-05-10T13:51:20+12:34" }), true, true, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"2016-05-10T13:51:20+12:34\"]}"), + new JsonProtocolTestData("InvocationMessage_HasNonAsciiArgument", new InvocationMessage("Method", new object[] { "מחרוזת כלשהי" }), true, true, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"מחרוזת כלשהי\"]}"), + new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNoCamelCase", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), false, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnore", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), false, false, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueInclude", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), true, false, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("StreamItemMessage_HasHeaders", AddHeaders(TestHeaders, new StreamItemMessage("123", new CustomObject())), true, false, "{\"type\":2," + SerializedHeaders + ",\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNoCamelCase", new StreamItemMessage("123", new CustomObject()), false, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueIgnore", new StreamItemMessage("123", new CustomObject()), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueIgnoreAndNoCamelCase", new StreamItemMessage("123", new CustomObject()), false, false, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueInclude", new StreamItemMessage("123", new CustomObject()), true, false, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), new JsonProtocolTestData("StreamItemMessage_HasIntegerItem", new StreamItemMessage("123", 1), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":1}"), new JsonProtocolTestData("StreamItemMessage_HasStringItem", new StreamItemMessage("123", "Foo"), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":\"Foo\"}"), new JsonProtocolTestData("StreamItemMessage_HasBoolItem", new StreamItemMessage("123", true), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":true}"), new JsonProtocolTestData("StreamItemMessage_HasNullItem", new StreamItemMessage("123", null), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":null}"), + new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNoCamelCase", CompletionMessage.WithResult("123", new CustomObject()), false, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueIgnore", CompletionMessage.WithResult("123", new CustomObject()), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueIncludeAndNoCamelCase", CompletionMessage.WithResult("123", new CustomObject()), false, false, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueInclude", CompletionMessage.WithResult("123", new CustomObject()), true, false, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("CompletionMessage_HasErrorAndCamelCase", CompletionMessage.Empty("123"), true, true, "{\"type\":3,\"invocationId\":\"123\"}"), + new JsonProtocolTestData("CompletionMessage_HasTestHeadersAndCustomItemResult", AddHeaders(TestHeaders, CompletionMessage.WithResult("123", new CustomObject())), true, false, "{\"type\":3," + SerializedHeaders + ",\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), + new JsonProtocolTestData("CompletionMessage_HasErrorAndHeadersAndCamelCase", AddHeaders(TestHeaders, CompletionMessage.Empty("123")), true, true, "{\"type\":3," + SerializedHeaders + ",\"invocationId\":\"123\"}"), new JsonProtocolTestData("CompletionMessage_HasIntegerResult", CompletionMessage.WithResult("123", 1), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":1}"), new JsonProtocolTestData("CompletionMessage_HasStringResult", CompletionMessage.WithResult("123", "Foo"), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":\"Foo\"}"), new JsonProtocolTestData("CompletionMessage_HasBoolResult", CompletionMessage.WithResult("123", true), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":true}"), @@ -53,6 +71,11 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol new JsonProtocolTestData("CompletionMessage_HasError", CompletionMessage.WithError("123", "Whoops!"), true, true, "{\"type\":3,\"invocationId\":\"123\",\"error\":\"Whoops!\"}"), new JsonProtocolTestData("CompletionMessage_HasErrorAndHeaders", AddHeaders(TestHeaders, CompletionMessage.WithError("123", "Whoops!")), true, true, "{\"type\":3," + SerializedHeaders + ",\"invocationId\":\"123\",\"error\":\"Whoops!\"}"), + new JsonProtocolTestData("StreamInvocationMessage_HasHeaders", AddHeaders(TestHeaders, new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() })), true, false, "{\"type\":4," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNoCamelCase", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), false, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueIgnore", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), false, false, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueInclude", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), true, false, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), new JsonProtocolTestData("StreamInvocationMessage_HasInvocationId", new StreamInvocationMessage("123", "Target", new object[] { 1, "Foo" }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\"]}"), new JsonProtocolTestData("StreamInvocationMessage_HasBoolArgument", new StreamInvocationMessage("123", "Target", new object[] { true }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[true]}"), new JsonProtocolTestData("StreamInvocationMessage_HasNullArgument", new StreamInvocationMessage("123", "Target", new object[] { null }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[null]}"), @@ -158,8 +181,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\"}", "Missing required property 'arguments'.")] [InlineData("{\"type\":4,\"invocationId\":\"42\",\"target\":\"foo\",\"arguments\":{}}", "Expected 'arguments' to be of type Array.")] - //[InlineData("{\"type\":3,\"invocationId\":\"42\",\"error\":\"foo\",\"result\":true}", "The 'error' and 'result' properties are mutually exclusive.")] - //[InlineData("{\"type\":3,\"invocationId\":\"42\",\"result\":true", "Unexpected end when reading JSON.")] + [InlineData("{\"type\":3,\"invocationId\":\"42\",\"error\":\"foo\",\"result\":true}", "The 'error' and 'result' properties are mutually exclusive.")] public void InvalidMessages(string input, string expectedMessage) { input = Frame(input); @@ -272,6 +294,70 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol Assert.Equal("foo", bindingFailure.Target); } + [Fact] + public void ReadCaseInsensitivePropertiesByDefault() + { + var input = Frame("{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StrIngProp\":\"test\",\"DoublePrOp\":3.14159,\"IntProp\":43,\"DateTimeProp\":\"2019-06-03T22:00:00\",\"NuLLProp\":null,\"ByteARRProp\":\"AgQG\"}}"); + + var binder = new TestBinder(null, typeof(CustomObject)); + var data = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(input)); + JsonHubProtocol.TryParseMessage(ref data, binder, out var message); + + var streamItemMessage = Assert.IsType<StreamItemMessage>(message); + Assert.Equal(new CustomObject() + { + ByteArrProp = new byte[] { 2, 4, 6 }, + IntProp = 43, + DoubleProp = 3.14159, + StringProp = "test", + DateTimeProp = DateTime.Parse("6/3/2019 10:00:00 PM") + }, streamItemMessage.Item); + } + + public static IDictionary<string, MessageSizeTestData> MessageSizeData => new[] + { + new MessageSizeTestData("InvocationMessage_WithoutInvocationId", new InvocationMessage("Target", new object[] { 1 }), 45), + new MessageSizeTestData("InvocationMessage_WithInvocationId", new InvocationMessage("1", "Target", new object[] { 1 }), 64), + new MessageSizeTestData("InvocationMessage_WithInvocationIdAndStreamId", new InvocationMessage("1", "Target", new object[] { 1 }, new string[] { "2" }), 82), + + new MessageSizeTestData("CloseMessage_Empty", CloseMessage.Empty, 11), + new MessageSizeTestData("CloseMessage_WithError", new CloseMessage("error"), 27), + + new MessageSizeTestData("StreamItemMessage_WithNullItem", new StreamItemMessage("1", null), 42), + new MessageSizeTestData("StreamItemMessage_WithItem", new StreamItemMessage("1", 1), 39), + + new MessageSizeTestData("CompletionMessage_Empty", CompletionMessage.Empty("1"), 30), + new MessageSizeTestData("CompletionMessage_WithResult", CompletionMessage.WithResult("1", 1), 41), + new MessageSizeTestData("CompletionMessage_WithError", CompletionMessage.WithError("1", "error"), 46), + + new MessageSizeTestData("StreamInvocationMessage", new StreamInvocationMessage("1", "target", Array.Empty<object>()), 63), + new MessageSizeTestData("StreamInvocationMessage_WithStreamId", new StreamInvocationMessage("1", "target", Array.Empty<object>(), new [] { "2" }), 81), + + new MessageSizeTestData("CancelInvocationMessage", new CancelInvocationMessage("1"), 30), + + new MessageSizeTestData("PingMessage", PingMessage.Instance, 11), + }.ToDictionary(t => t.Name); + + public static IEnumerable<object[]> MessageSizeDataNames => MessageSizeData.Keys.Select(name => new object[] { name }); + + [Theory] + [MemberData(nameof(MessageSizeDataNames))] + public void VerifyMessageSize(string testDataName) + { + var testData = MessageSizeData[testDataName]; + + var writer = MemoryBufferWriter.Get(); + try + { + JsonHubProtocol.WriteMessage(testData.Message, writer); + Assert.Equal(testData.Size, writer.Length); + } + finally + { + MemoryBufferWriter.Return(writer); + } + } + public static string Frame(string input) { var data = Encoding.UTF8.GetBytes(input); @@ -305,5 +391,21 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol public override string ToString() => Name; } + + public class MessageSizeTestData + { + public string Name { get; } + public HubMessage Message { get; } + public int Size { get; } + + public MessageSizeTestData(string name, HubMessage message, int size) + { + Name = name; + Message = message; + Size = size; + } + + public override string ToString() => Name; + } } } diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/MessagePackHubProtocolTests.cs b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/MessagePackHubProtocolTests.cs index 8134f8e9bf..8a87a67bd6 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/MessagePackHubProtocolTests.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/MessagePackHubProtocolTests.cs @@ -195,5 +195,55 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol TestWriteMessages(testData); } + + public static IDictionary<string, MessageSizeTestData> MessageSizeData => new[] + { + new MessageSizeTestData("InvocationMessage_WithoutInvocationId", new InvocationMessage("Target", new object[] { 1 }), 15), + new MessageSizeTestData("InvocationMessage_WithInvocationId", new InvocationMessage("1", "Target", new object[] { 1 }), 16), + new MessageSizeTestData("InvocationMessage_WithInvocationIdAndStreamId", new InvocationMessage("1", "Target", new object[] { 1 }, new string[] { "2" }), 18), + + new MessageSizeTestData("CloseMessage_Empty", CloseMessage.Empty, 5), + new MessageSizeTestData("CloseMessage_WithError", new CloseMessage("error"), 10), + + new MessageSizeTestData("StreamItemMessage_WithNullItem", new StreamItemMessage("1", null), 7), + new MessageSizeTestData("StreamItemMessage_WithItem", new StreamItemMessage("1", 1), 7), + + new MessageSizeTestData("CompletionMessage_Empty", CompletionMessage.Empty("1"), 7), + new MessageSizeTestData("CompletionMessage_WithResult", CompletionMessage.WithResult("1", 1), 8), + new MessageSizeTestData("CompletionMessage_WithError", CompletionMessage.WithError("1", "error"), 13), + + new MessageSizeTestData("StreamInvocationMessage", new StreamInvocationMessage("1", "target", Array.Empty<object>()), 15), + new MessageSizeTestData("StreamInvocationMessage_WithStreamId", new StreamInvocationMessage("1", "target", Array.Empty<object>(), new [] { "2" }), 17), + + new MessageSizeTestData("CancelInvocationMessage", new CancelInvocationMessage("1"), 6), + + new MessageSizeTestData("PingMessage", PingMessage.Instance, 3), + }.ToDictionary(t => t.Name); + + public static IEnumerable<object[]> MessageSizeDataNames => MessageSizeData.Keys.Select(name => new object[] { name }); + + [Theory] + [MemberData(nameof(MessageSizeDataNames))] + public void VerifyMessageSize(string testDataName) + { + var testData = MessageSizeData[testDataName]; + Assert.Equal(testData.Size, Write(testData.Message).Length); + } + + public class MessageSizeTestData + { + public string Name { get; } + public HubMessage Message { get; } + public int Size { get; } + + public MessageSizeTestData(string name, HubMessage message, int size) + { + Name = name; + Message = message; + Size = size; + } + + public override string ToString() => Name; + } } } diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/NewtonsoftJsonHubProtocolTests.cs b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/NewtonsoftJsonHubProtocolTests.cs index 255cdead83..de10b1dbf6 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/NewtonsoftJsonHubProtocolTests.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/NewtonsoftJsonHubProtocolTests.cs @@ -40,6 +40,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol [InlineData("", "Unexpected end when reading JSON.")] [InlineData("42", "Unexpected JSON Token Type 'Integer'. Expected a JSON Object.")] [InlineData("{\"type\":\"foo\"}", "Expected 'type' to be of type Integer.")] + [InlineData("{\"type\":3,\"invocationId\":\"42\",\"result\":true", "Unexpected end when reading JSON.")] public void CustomInvalidMessages(string input, string expectedMessage) { input = Frame(input); @@ -93,35 +94,13 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol public static IDictionary<string, JsonProtocolTestData> CustomProtocolTestData => new[] { new JsonProtocolTestData("InvocationMessage_HasFloatArgument", new InvocationMessage(null, "Target", new object[] { 1, "Foo", 2.0f }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"), - new JsonProtocolTestData("InvocationMessage_StringIsoDateArgument", new InvocationMessage("Method", new object[] { "2016-05-10T13:51:20+12:34" }), false, true, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"2016-05-10T13:51:20+12:34\"]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNoCamelCase", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), false, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnore", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), false, false, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueInclude", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), true, false, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), new JsonProtocolTestData("InvocationMessage_HasHeaders", AddHeaders(TestHeaders, new InvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f })), true, true, "{\"type\":1," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"), new JsonProtocolTestData("StreamItemMessage_HasFloatItem", new StreamItemMessage("123", 2.0f), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":2.0}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNoCamelCase", new StreamItemMessage("123", new CustomObject()), false, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueIgnore", new StreamItemMessage("123", new CustomObject()), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueIgnoreAndNoCamelCase", new StreamItemMessage("123", new CustomObject()), false, false, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueInclude", new StreamItemMessage("123", new CustomObject()), true, false, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("StreamItemMessage_HasHeaders", AddHeaders(TestHeaders, new StreamItemMessage("123", new CustomObject())), true, false, "{\"type\":2," + SerializedHeaders + ",\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNoCamelCase", CompletionMessage.WithResult("123", new CustomObject()), false, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueIgnore", CompletionMessage.WithResult("123", new CustomObject()), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueIncludeAndNoCamelCase", CompletionMessage.WithResult("123", new CustomObject()), false, false, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasCustomResultWithNullValueInclude", CompletionMessage.WithResult("123", new CustomObject()), true, false, "{\"type\":3,\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasTestHeadersAndCustomItemResult", AddHeaders(TestHeaders, CompletionMessage.WithResult("123", new CustomObject())), true, false, "{\"type\":3," + SerializedHeaders + ",\"invocationId\":\"123\",\"result\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasErrorAndCamelCase", CompletionMessage.Empty("123"), true, true, "{\"type\":3,\"invocationId\":\"123\"}"), - new JsonProtocolTestData("CompletionMessage_HasErrorAndHeadersAndCamelCase", AddHeaders(TestHeaders, CompletionMessage.Empty("123")), true, true, "{\"type\":3," + SerializedHeaders + ",\"invocationId\":\"123\"}"), new JsonProtocolTestData("CompletionMessage_HasFloatResult", CompletionMessage.WithResult("123", 2.0f), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":2.0}"), new JsonProtocolTestData("StreamInvocationMessage_HasFloatArgument", new StreamInvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNoCamelCase", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), false, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueIgnore", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), false, false, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasCustomArgumentWithNullValueInclude", new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() }), true, false, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), - new JsonProtocolTestData("StreamInvocationMessage_HasHeaders", AddHeaders(TestHeaders, new StreamInvocationMessage("123", "Target", new object[] { new CustomObject() })), true, false, "{\"type\":4," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), }.ToDictionary(t => t.Name); public static IEnumerable<object[]> CustomProtocolTestDataNames => CustomProtocolTestData.Keys.Select(name => new object[] { name }); diff --git a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/Utf8BufferTextWriterTests.cs b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/Utf8BufferTextWriterTests.cs index b1fe8c76fb..6b7a5563d3 100644 --- a/src/SignalR/common/SignalR.Common/test/Internal/Protocol/Utf8BufferTextWriterTests.cs +++ b/src/SignalR/common/SignalR.Common/test/Internal/Protocol/Utf8BufferTextWriterTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -245,7 +245,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol } [Fact] - private void WriteMultiByteCharactersToSmallBuffers() + public void WriteMultiByteCharactersToSmallBuffers() { // Test string breakdown (char => UTF-8 hex values): // a => 61 diff --git a/src/SignalR/docs/specs/TransportProtocols.md b/src/SignalR/docs/specs/TransportProtocols.md index f11b80bc74..a4c10f4ead 100644 --- a/src/SignalR/docs/specs/TransportProtocols.md +++ b/src/SignalR/docs/specs/TransportProtocols.md @@ -12,19 +12,65 @@ A transport is required to have the following attributes: The only transport which fully implements the duplex requirement is WebSockets, the others are "half-transports" which implement one end of the duplex connection. They are used in combination to achieve a duplex connection. -Throughout this document, the term `[endpoint-base]` is used to refer to the route assigned to a particular end point. The term `[connection-id]` is used to refer to the connection ID provided by the `POST [endpoint-base]/negotiate` request. +Throughout this document, the term `[endpoint-base]` is used to refer to the route assigned to a particular end point. The terms `connection-id` and `connectionToken` are used to refer to the connection ID and connection token provided by the `POST [endpoint-base]/negotiate` request. **NOTE on errors:** In all error cases, by default, the detailed exception message is **never** provided; a short description string may be provided. However, an application developer may elect to allow detailed exception messages to be emitted, which should only be used in the `Development` environment. Unexpected errors are communicated by HTTP `500 Server Error` status codes or WebSockets non-`1000 Normal Closure` close frames; in these cases the connection should be considered to be terminated. ## `POST [endpoint-base]/negotiate` request -The `POST [endpoint-base]/negotiate` request is used to establish a connection between the client and the server. The content type of the response is `application/json`. The response to the `POST [endpoint-base]/negotiate` request contains one of three types of responses: +The `POST [endpoint-base]/negotiate` request is used to establish a connection between the client and the server. -1. A response that contains the `connectionId` which will be used to identify the connection on the server and the list of the transports supported by the server. +In the POST request the client sends a query string parameter with the key "negotiateVersion" and the value as the negotiate protocol version it would like to use. If the query string is omitted, the server treats the version as zero. The server will include a "negotiateVersion" property in the json response that says which version it will be using. The version is chosen as described below: +* If the servers minimum supported protocol version is greater than the version requested by the client it will send an error response and close the connection +* If the server supports the request version it will respond with the requested version +* If the requested version is greater than the servers largest supported version the server will respond with its largest supported version +The client may close the connection if the "negotiateVersion" in the response is not acceptable. +The content type of the response is `application/json` and is a JSON payload containing properties to assist the client in establishing a persistent connection. Extra JSON properties that the client does not know about should be ignored. This allows for future additions without breaking older clients. + +### Version 1 + +When the server and client agree on version 1 the server response will include a "connectionToken" property in addition to the "connectionId" property. The value of the "connectionToken" property will be used in the "id" query string for the HTTP requests described below, this value should be kept secret. + +A successful negotiate response will look similar to the following payload: + ```json + { + "connectionToken":"05265228-1e2c-46c5-82a1-6a5bcc3f0143", + "connectionId":"807809a5-31bf-470d-9e23-afaee35d8a0d", + "negotiateVersion":1, + "availableTransports":[ + { + "transport": "WebSockets", + "transferFormats": [ "Text", "Binary" ] + }, + { + "transport": "ServerSentEvents", + "transferFormats": [ "Text" ] + }, + { + "transport": "LongPolling", + "transferFormats": [ "Text", "Binary" ] + } + ] + } + ``` + + The payload returned from this endpoint provides the following data: + + * The `connectionToken` which is **required** by the Long Polling and Server-Sent Events transports (in order to correlate sends and receives). + * The `connectionId` which is the id by which other clients can refer to it. + * The `negotiateVersion` which is the negotiation protocol version being used between the server and client. + * The `availableTransports` list which describes the transports the server supports. For each transport, the name of the transport (`transport`) is listed, as is a list of "transfer formats" supported by the transport (`transferFormats`) + +### Version 0 + +When the server and client agree on version 0 the server response will include a "connectionId" property that is used in the "id" query string for the HTTP requests described below. + +A successful negotiate response will look similar to the following payload: ```json { "connectionId":"807809a5-31bf-470d-9e23-afaee35d8a0d", + "negotiateVersion":0, "availableTransports":[ { "transport": "WebSockets", @@ -45,10 +91,14 @@ The `POST [endpoint-base]/negotiate` request is used to establish a connection b The payload returned from this endpoint provides the following data: * The `connectionId` which is **required** by the Long Polling and Server-Sent Events transports (in order to correlate sends and receives). + * The `negotiateVersion` which is the negotiation protocol version being used between the server and client. * The `availableTransports` list which describes the transports the server supports. For each transport, the name of the transport (`transport`) is listed, as is a list of "transfer formats" supported by the transport (`transferFormats`) +### All versions -2. A redirect response which tells the client which URL and optionally access token to use as a result. +There are two other possible negotiation responses: + +1. A redirect response which tells the client which URL and optionally access token to use as a result. ```json { @@ -63,7 +113,7 @@ The `POST [endpoint-base]/negotiate` request is used to establish a connection b * The `accessToken` which is an optional bearer token for accessing the specified url. -3. A response that contains an `error` which should stop the connection attempt. +1. A response that contains an `error` which should stop the connection attempt. ```json { @@ -136,10 +186,14 @@ Long Polling requires that the client poll the server for new messages. Unlike t A Poll is established by sending an HTTP GET request to `[endpoint-base]` with the following query string parameters +#### Version 1 +* `id` (Required) - The Connection Token of the destination connection. + +#### Version 0 * `id` (Required) - The Connection ID of the destination connection. When data is available, the server responds with a body in one of the two formats below (depending upon the value of the `Accept` header). The response may be chunked, as per the chunked encoding part of the HTTP spec. If the `id` parameter is missing, a `400 Bad Request` response is returned. If there is no connection with the ID specified in `id`, a `404 Not Found` response is returned. -When the client has finished with the connection, it can issue a `DELETE` request to `[endpoint-base]` (with the `id` in the querystring) to gracefully terminate the connection. The server will complete the latest poll with `204` to indicate that it has shut down. +When the client has finished with the connection, it can issue a `DELETE` request to `[endpoint-base]` (with the `id` in the query string) to gracefully terminate the connection. The server will complete the latest poll with `204` to indicate that it has shut down. diff --git a/src/SignalR/perf/Microbenchmarks/TypedClientBuilderBenchmark.cs b/src/SignalR/perf/Microbenchmarks/TypedClientBuilderBenchmark.cs new file mode 100644 index 0000000000..8a386fd228 --- /dev/null +++ b/src/SignalR/perf/Microbenchmarks/TypedClientBuilderBenchmark.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.SignalR.Internal; + +namespace Microsoft.AspNetCore.SignalR.Microbenchmarks +{ + public class TypedClientBuilderBenchmark + { + private static readonly IClientProxy Dummy = new DummyProxy(); + + [Benchmark] + public ITestClient Build() + { + return TypedClientBuilder<ITestClient>.Build(Dummy); + } + + public interface ITestClient { } + + private class DummyProxy : IClientProxy + { + public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + } + } +} diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Commands/Defaults.cs b/src/SignalR/perf/benchmarkapps/Crankier/Commands/Defaults.cs index 732ccb6af3..84027fff16 100644 --- a/src/SignalR/perf/benchmarkapps/Crankier/Commands/Defaults.cs +++ b/src/SignalR/perf/benchmarkapps/Crankier/Commands/Defaults.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.Http.Connections; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.SignalR.Crankier.Commands { @@ -11,5 +12,6 @@ namespace Microsoft.AspNetCore.SignalR.Crankier.Commands public static readonly int NumberOfConnections = 10_000; public static readonly int SendDurationInSeconds = 300; public static readonly HttpTransportType TransportType = HttpTransportType.WebSockets; + public static readonly LogLevel LogLevel = LogLevel.None; } } diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Commands/ServerCommand.cs b/src/SignalR/perf/benchmarkapps/Crankier/Commands/ServerCommand.cs new file mode 100644 index 0000000000..738d3232fd --- /dev/null +++ b/src/SignalR/perf/benchmarkapps/Crankier/Commands/ServerCommand.cs @@ -0,0 +1,75 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http.Connections; +using Microsoft.Extensions.CommandLineUtils; +using static Microsoft.AspNetCore.SignalR.Crankier.Commands.CommandLineUtilities; +using System.Diagnostics; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.SignalR.Crankier.Server; +using System.Collections.Generic; + +namespace Microsoft.AspNetCore.SignalR.Crankier.Commands +{ + internal class ServerCommand + { + public static void Register(CommandLineApplication app) + { + app.Command("server", cmd => + { + var logLevelOption = cmd.Option("--log <LOG_LEVEL>", "The LogLevel to use.", CommandOptionType.SingleValue); + var azureSignalRConnectionString = cmd.Option("--azure-signalr-connectionstring <CONNECTION_STRING>", "Azure SignalR Connection string to use", CommandOptionType.SingleValue); + + cmd.OnExecute(() => + { + LogLevel logLevel = Defaults.LogLevel; + + if (logLevelOption.HasValue() && !Enum.TryParse(logLevelOption.Value(), out logLevel)) + { + return InvalidArg(logLevelOption); + } + + if (azureSignalRConnectionString.HasValue() && string.IsNullOrWhiteSpace(azureSignalRConnectionString.Value())) + { + return InvalidArg(azureSignalRConnectionString); + } + + return Execute(logLevel, azureSignalRConnectionString.Value()); + }); + }); + } + + private static int Execute(LogLevel logLevel, string azureSignalRConnectionString) + { + Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}"); + + var configBuilder = new ConfigurationBuilder() + .AddEnvironmentVariables(prefix: "ASPNETCORE_"); + + if (azureSignalRConnectionString != null) + { + configBuilder.AddInMemoryCollection(new [] { new KeyValuePair<string, string>("Azure:SignalR:ConnectionString", azureSignalRConnectionString) }); + Console.WriteLine("Using Azure SignalR"); + } + + var config = configBuilder.Build(); + + var host = new WebHostBuilder() + .UseConfiguration(config) + .ConfigureLogging(loggerFactory => + { + loggerFactory.AddConsole().SetMinimumLevel(logLevel); + }) + .UseKestrel() + .UseStartup<Startup>(); + + host.Build().Run(); + + return 0; + } + } +} diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Crankier.csproj b/src/SignalR/perf/benchmarkapps/Crankier/Crankier.csproj index 1c1b18a058..23ae6b0027 100644 --- a/src/SignalR/perf/benchmarkapps/Crankier/Crankier.csproj +++ b/src/SignalR/perf/benchmarkapps/Crankier/Crankier.csproj @@ -4,12 +4,19 @@ <OutputType>Exe</OutputType> <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework> <RootNamespace>Microsoft.AspNetCore.SignalR.CranksRevenge</RootNamespace> + <DisableTransitiveFrameworkReferences>true</DisableTransitiveFrameworkReferences> </PropertyGroup> <ItemGroup> <Reference Include="Microsoft.AspNetCore.SignalR.Client" /> <Reference Include="Microsoft.Extensions.CommandLineUtils.Sources" /> + <Reference Include="Microsoft.AspNetCore.SignalR" /> + <Reference Include="Microsoft.AspNetCore.Server.Kestrel" /> + <Reference Include="Microsoft.Extensions.Configuration.CommandLine" /> + <Reference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" /> + <Reference Include="Microsoft.Extensions.Logging.Console" /> <Reference Include="Newtonsoft.Json" /> + <Reference Include="Microsoft.Azure.SignalR" /> </ItemGroup> </Project> diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Program.cs b/src/SignalR/perf/benchmarkapps/Crankier/Program.cs index a3443ecd94..93f53ea328 100644 --- a/src/SignalR/perf/benchmarkapps/Crankier/Program.cs +++ b/src/SignalR/perf/benchmarkapps/Crankier/Program.cs @@ -30,6 +30,7 @@ namespace Microsoft.AspNetCore.SignalR.Crankier LocalCommand.Register(app); AgentCommand.Register(app); WorkerCommand.Register(app); + ServerCommand.Register(app); app.Command("help", cmd => { diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Readme.md b/src/SignalR/perf/benchmarkapps/Crankier/Readme.md index 20f56cc720..dc783bcc9e 100644 --- a/src/SignalR/perf/benchmarkapps/Crankier/Readme.md +++ b/src/SignalR/perf/benchmarkapps/Crankier/Readme.md @@ -4,6 +4,26 @@ Load testing for ASP.NET Core SignalR ## Commands +### server + +The `server` command runs a web host exposing a single SignalR `Hub` endpoint on `/echo`. After the first client connection, the server will periodically write concurrent connection information to the console. + +``` +> dotnet run -- help server + +Usage: server [options] + +Options: + --log <LOG_LEVEL> The LogLevel to use. + --azure-signalr-connectionstring <CONNECTION_STRING> Azure SignalR Connection string to use + +``` + +Notes: + +* `LOG_LEVEL` switches internal logging only, not concurrent connection information, and defaults to `LogLevel.None`. Use this option to control Kestrel / SignalR Warnings & Errors being logged to console. + + ### local The `local` command launches a set of local worker clients to establish connections to your SignalR server. @@ -31,13 +51,25 @@ Notes: #### Examples -Attempt to make 10,000 connections to the `echo` hub using WebSockets and 10 workers: +Run the server: + +``` +dotnet run -- server +``` + +Run the server using Azure SignalR: + +``` +dotnet run -- server --azure-signalr-connectionstring Endpoint=https://your-url.service.signalr.net;AccessKey=yourAccessKey;Version=1.0; +``` + +Attempt to make 10,000 connections to the server using WebSockets and 10 workers: ``` dotnet run -- local --target-url https://localhost:5001/echo --workers 10 ``` -Attempt to make 5,000 connections to the `echo` hub using Long Polling +Attempt to make 5,000 connections to the server using Long Polling ``` dotnet run -- local --target-url https://localhost:5001/echo --connections 5000 --transport LongPolling diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionCounter.cs b/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionCounter.cs new file mode 100644 index 0000000000..1ab6a25abc --- /dev/null +++ b/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionCounter.cs @@ -0,0 +1,60 @@ +// 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; + +namespace Microsoft.AspNetCore.SignalR.Crankier.Server +{ + public class ConnectionCounter + { + private int _totalConnectedCount; + private int _peakConnectedCount; + private int _totalDisconnectedCount; + private int _receivedCount; + + private readonly object _lock = new object(); + + public ConnectionSummary Summary + { + get + { + lock (_lock) + { + return new ConnectionSummary + { + CurrentConnections = _totalConnectedCount - _totalDisconnectedCount, + PeakConnections = _peakConnectedCount, + TotalConnected = _totalConnectedCount, + TotalDisconnected = _totalDisconnectedCount, + ReceivedCount = _receivedCount + }; + } + } + } + + public void Receive(string payload) + { + lock (_lock) + { + _receivedCount += payload.Length; + } + } + + public void Connected() + { + lock (_lock) + { + _totalConnectedCount++; + _peakConnectedCount = Math.Max(_totalConnectedCount - _totalDisconnectedCount, _peakConnectedCount); + } + } + + public void Disconnected() + { + lock (_lock) + { + _totalDisconnectedCount++; + } + } + } +} \ No newline at end of file diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionCounterHostedService.cs b/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionCounterHostedService.cs new file mode 100644 index 0000000000..44b8bb26f2 --- /dev/null +++ b/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionCounterHostedService.cs @@ -0,0 +1,79 @@ +// 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.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; + +namespace Microsoft.AspNetCore.SignalR.Crankier.Server +{ + public class ConnectionCounterHostedService : IHostedService, IDisposable + { + private Stopwatch _timeSinceFirstConnection; + private readonly ConnectionCounter _counter; + private ConnectionSummary _lastSummary; + private Timer _timer; + private int _executingDoWork; + + public ConnectionCounterHostedService(ConnectionCounter counter) + { + _counter = counter; + _timeSinceFirstConnection = new Stopwatch(); + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + + return Task.CompletedTask; + } + + private void DoWork(object state) + { + if (Interlocked.Exchange(ref _executingDoWork, 1) == 0) + { + var summary = _counter.Summary; + + if (summary.PeakConnections > 0) + { + if (_timeSinceFirstConnection.ElapsedTicks == 0) + { + _timeSinceFirstConnection.Start(); + } + + var elapsed = _timeSinceFirstConnection.Elapsed; + + if (_lastSummary != null) + { + Console.WriteLine(@"[{0:hh\:mm\:ss}] Current: {1}, peak: {2}, connected: {3}, disconnected: {4}, rate: {5}/s", + elapsed, + summary.CurrentConnections, + summary.PeakConnections, + summary.TotalConnected - _lastSummary.TotalConnected, + summary.TotalDisconnected - _lastSummary.TotalDisconnected, + summary.CurrentConnections - _lastSummary.CurrentConnections + ); + } + + _lastSummary = summary; + } + + Interlocked.Exchange(ref _executingDoWork, 0); + } + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _timer?.Change(Timeout.Infinite, 0); + + return Task.CompletedTask; + } + + public void Dispose() + { + _timer?.Dispose(); + } + } +} \ No newline at end of file diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionSummary.cs b/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionSummary.cs new file mode 100644 index 0000000000..83f38aaf62 --- /dev/null +++ b/src/SignalR/perf/benchmarkapps/Crankier/Server/ConnectionSummary.cs @@ -0,0 +1,18 @@ +// 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. + +namespace Microsoft.AspNetCore.SignalR.Crankier.Server +{ + public class ConnectionSummary + { + public int TotalConnected { get; set; } + + public int TotalDisconnected { get; set; } + + public int PeakConnections { get; set; } + + public int CurrentConnections { get; set; } + + public int ReceivedCount { get; set; } + } +} \ No newline at end of file diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Server/EchoHub.cs b/src/SignalR/perf/benchmarkapps/Crankier/Server/EchoHub.cs new file mode 100644 index 0000000000..0b24b46e9b --- /dev/null +++ b/src/SignalR/perf/benchmarkapps/Crankier/Server/EchoHub.cs @@ -0,0 +1,72 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR; + +namespace Microsoft.AspNetCore.SignalR.Crankier.Server +{ + public class EchoHub : Hub + { + private ConnectionCounter _counter; + + public EchoHub(ConnectionCounter counter) + { + _counter = counter; + } + + public async Task Broadcast(int duration) + { + var sent = 0; + try + { + var t = new CancellationTokenSource(); + t.CancelAfter(TimeSpan.FromSeconds(duration)); + while (!t.IsCancellationRequested && !Context.ConnectionAborted.IsCancellationRequested) + { + await Clients.All.SendAsync("send", DateTime.UtcNow); + sent++; + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + Console.WriteLine("Broadcast exited: Sent {0} messages", sent); + } + + public override Task OnConnectedAsync() + { + _counter?.Connected(); + return Task.CompletedTask; + } + + public override Task OnDisconnectedAsync(Exception exception) + { + _counter?.Disconnected(); + return Task.CompletedTask; + } + + public DateTime Echo(DateTime time) + { + return time; + } + + public Task EchoAll(DateTime time) + { + return Clients.All.SendAsync("send", time); + } + + public void SendPayload(string payload) + { + _counter?.Receive(payload); + } + + public DateTime GetCurrentTime() + { + return DateTime.UtcNow; + } + } +} diff --git a/src/SignalR/perf/benchmarkapps/Crankier/Server/Startup.cs b/src/SignalR/perf/benchmarkapps/Crankier/Server/Startup.cs new file mode 100644 index 0000000000..6b3154416c --- /dev/null +++ b/src/SignalR/perf/benchmarkapps/Crankier/Server/Startup.cs @@ -0,0 +1,57 @@ +// 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 Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.SignalR.Crankier.Server +{ + public class Startup + { + private readonly IConfiguration _config; + private readonly string _azureSignalrConnectionString; + public Startup(IConfiguration configuration) + { + _config = configuration; + _azureSignalrConnectionString = configuration.GetSection("Azure:SignalR").GetValue<string>("ConnectionString", null); + } + + public void ConfigureServices(IServiceCollection services) + { + var signalrBuilder = services.AddSignalR(); + + if (_azureSignalrConnectionString != null) + { + signalrBuilder.AddAzureSignalR(); + } + + signalrBuilder.AddMessagePackProtocol(); + + services.AddSingleton<ConnectionCounter>(); + + services.AddHostedService<ConnectionCounterHostedService>(); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + app.UseRouting(); + + if (_azureSignalrConnectionString != null) + { + app.UseAzureSignalR(routes => { + routes.MapHub<EchoHub>("/echo"); + }); + } + else + { + app.UseEndpoints(endpoints => + { + endpoints.MapHub<EchoHub>("/echo"); + }); + } + } + } +} diff --git a/src/SignalR/publish-apps.ps1 b/src/SignalR/publish-apps.ps1 index fcb8c99cae..8c7b2de4a4 100644 --- a/src/SignalR/publish-apps.ps1 +++ b/src/SignalR/publish-apps.ps1 @@ -1,4 +1,4 @@ -param($RootDirectory = (Get-Location), $Framework = "netcoreapp3.1", $Runtime = "win-x64", $CommitHash, $BranchName, $BuildNumber) +param($RootDirectory = (Get-Location), $Framework = "netcoreapp5.0", $Runtime = "win-x64", $CommitHash, $BranchName, $BuildNumber) # De-Powershell the path $RootDirectory = (Convert-Path $RootDirectory) diff --git a/src/SignalR/server/Core/ref/Microsoft.AspNetCore.SignalR.Core.netcoreapp.cs b/src/SignalR/server/Core/ref/Microsoft.AspNetCore.SignalR.Core.netcoreapp.cs index 5309dae32c..f23da84b52 100644 --- a/src/SignalR/server/Core/ref/Microsoft.AspNetCore.SignalR.Core.netcoreapp.cs +++ b/src/SignalR/server/Core/ref/Microsoft.AspNetCore.SignalR.Core.netcoreapp.cs @@ -84,6 +84,7 @@ namespace Microsoft.AspNetCore.SignalR } public static partial class HubClientsExtensions { + public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, System.Collections.Generic.IEnumerable<string> excludedConnectionIds) { throw null; } public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string excludedConnectionId1) { throw null; } public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string excludedConnectionId1, string excludedConnectionId2) { throw null; } public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3) { throw null; } @@ -92,6 +93,7 @@ namespace Microsoft.AspNetCore.SignalR public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3, string excludedConnectionId4, string excludedConnectionId5, string excludedConnectionId6) { throw null; } public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3, string excludedConnectionId4, string excludedConnectionId5, string excludedConnectionId6, string excludedConnectionId7) { throw null; } public static T AllExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3, string excludedConnectionId4, string excludedConnectionId5, string excludedConnectionId6, string excludedConnectionId7, string excludedConnectionId8) { throw null; } + public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, System.Collections.Generic.IEnumerable<string> connectionIds) { throw null; } public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string connection1) { throw null; } public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string connection1, string connection2) { throw null; } public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string connection1, string connection2, string connection3) { throw null; } @@ -100,6 +102,7 @@ namespace Microsoft.AspNetCore.SignalR public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string connection1, string connection2, string connection3, string connection4, string connection5, string connection6) { throw null; } public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string connection1, string connection2, string connection3, string connection4, string connection5, string connection6, string connection7) { throw null; } public static T Clients<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string connection1, string connection2, string connection3, string connection4, string connection5, string connection6, string connection7, string connection8) { throw null; } + public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, System.Collections.Generic.IEnumerable<string> excludedConnectionIds) { throw null; } public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, string excludedConnectionId1) { throw null; } public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, string excludedConnectionId1, string excludedConnectionId2) { throw null; } public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3) { throw null; } @@ -108,6 +111,7 @@ namespace Microsoft.AspNetCore.SignalR public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3, string excludedConnectionId4, string excludedConnectionId5, string excludedConnectionId6) { throw null; } public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3, string excludedConnectionId4, string excludedConnectionId5, string excludedConnectionId6, string excludedConnectionId7) { throw null; } public static T GroupExcept<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string groupName, string excludedConnectionId1, string excludedConnectionId2, string excludedConnectionId3, string excludedConnectionId4, string excludedConnectionId5, string excludedConnectionId6, string excludedConnectionId7, string excludedConnectionId8) { throw null; } + public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, System.Collections.Generic.IEnumerable<string> groupNames) { throw null; } public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string group1) { throw null; } public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string group1, string group2) { throw null; } public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string group1, string group2, string group3) { throw null; } @@ -116,6 +120,7 @@ namespace Microsoft.AspNetCore.SignalR public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string group1, string group2, string group3, string group4, string group5, string group6) { throw null; } public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string group1, string group2, string group3, string group4, string group5, string group6, string group7) { throw null; } public static T Groups<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string group1, string group2, string group3, string group4, string group5, string group6, string group7, string group8) { throw null; } + public static T Users<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, System.Collections.Generic.IEnumerable<string> userIds) { throw null; } public static T Users<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string user1) { throw null; } public static T Users<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string user1, string user2) { throw null; } public static T Users<T>(this Microsoft.AspNetCore.SignalR.IHubClients<T> hubClients, string user1, string user2, string user3) { throw null; } @@ -128,13 +133,13 @@ namespace Microsoft.AspNetCore.SignalR public partial class HubConnectionContext { public HubConnectionContext(Microsoft.AspNetCore.Connections.ConnectionContext connectionContext, Microsoft.AspNetCore.SignalR.HubConnectionContextOptions contextOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { } - public virtual System.Threading.CancellationToken ConnectionAborted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual System.Threading.CancellationToken ConnectionAborted { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public virtual string ConnectionId { get { throw null; } } public virtual Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get { throw null; } } public virtual System.Collections.Generic.IDictionary<object, object> Items { get { throw null; } } - public virtual Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public virtual Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol Protocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual System.Security.Claims.ClaimsPrincipal User { get { throw null; } } - public string UserIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public string UserIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public virtual void Abort() { } public virtual System.Threading.Tasks.ValueTask WriteAsync(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public virtual System.Threading.Tasks.ValueTask WriteAsync(Microsoft.AspNetCore.SignalR.SerializedHubMessage message, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } @@ -142,10 +147,10 @@ namespace Microsoft.AspNetCore.SignalR public partial class HubConnectionContextOptions { public HubConnectionContextOptions() { } - public System.TimeSpan ClientTimeoutInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long? MaximumReceiveMessageSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int StreamBufferCapacity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan ClientTimeoutInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaximumReceiveMessageSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int StreamBufferCapacity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HubConnectionHandler<THub> : Microsoft.AspNetCore.Connections.ConnectionHandler where THub : Microsoft.AspNetCore.SignalR.Hub { @@ -165,6 +170,7 @@ namespace Microsoft.AspNetCore.SignalR public readonly partial struct Enumerator : System.Collections.Generic.IEnumerator<Microsoft.AspNetCore.SignalR.HubConnectionContext>, System.Collections.IEnumerator, System.IDisposable { private readonly object _dummy; + private readonly int _dummyPrimitive; public Enumerator(Microsoft.AspNetCore.SignalR.HubConnectionStore hubConnectionList) { throw null; } public Microsoft.AspNetCore.SignalR.HubConnectionContext Current { get { throw null; } } object System.Collections.IEnumerator.Current { get { throw null; } } @@ -176,9 +182,11 @@ namespace Microsoft.AspNetCore.SignalR public partial class HubInvocationContext { public HubInvocationContext(Microsoft.AspNetCore.SignalR.HubCallerContext context, string hubMethodName, object[] hubMethodArguments) { } - public Microsoft.AspNetCore.SignalR.HubCallerContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.Collections.Generic.IReadOnlyList<object> HubMethodArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string HubMethodName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public HubInvocationContext(Microsoft.AspNetCore.SignalR.HubCallerContext context, System.Type hubType, string hubMethodName, object[] hubMethodArguments) { } + public Microsoft.AspNetCore.SignalR.HubCallerContext Context { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Collections.Generic.IReadOnlyList<object> HubMethodArguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public string HubMethodName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.Type HubType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public abstract partial class HubLifetimeManager<THub> where THub : Microsoft.AspNetCore.SignalR.Hub { @@ -200,24 +208,24 @@ namespace Microsoft.AspNetCore.SignalR public partial class HubMetadata { public HubMetadata(System.Type hubType) { } - public System.Type HubType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public System.Type HubType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } [System.AttributeUsageAttribute(System.AttributeTargets.Method, AllowMultiple=false, Inherited=true)] public partial class HubMethodNameAttribute : System.Attribute { public HubMethodNameAttribute(string name) { } - public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public partial class HubOptions { public HubOptions() { } - public System.TimeSpan? ClientTimeoutInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public bool? EnableDetailedErrors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan? HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.TimeSpan? KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public long? MaximumReceiveMessageSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public int? StreamBufferCapacity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Collections.Generic.IList<string> SupportedProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public System.TimeSpan? ClientTimeoutInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public bool? EnableDetailedErrors { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan? HandshakeTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.TimeSpan? KeepAliveInterval { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public long? MaximumReceiveMessageSize { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public int? StreamBufferCapacity { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Collections.Generic.IList<string> SupportedProtocols { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } public partial class HubOptionsSetup : Microsoft.Extensions.Options.IConfigureOptions<Microsoft.AspNetCore.SignalR.HubOptions> { @@ -302,16 +310,17 @@ namespace Microsoft.AspNetCore.SignalR { public SerializedHubMessage(Microsoft.AspNetCore.SignalR.Protocol.HubMessage message) { } public SerializedHubMessage(System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.SignalR.SerializedMessage> messages) { } - public Microsoft.AspNetCore.SignalR.Protocol.HubMessage Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public Microsoft.AspNetCore.SignalR.Protocol.HubMessage Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.ReadOnlyMemory<byte> GetSerializedMessage(Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol protocol) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct SerializedMessage { private readonly object _dummy; + private readonly int _dummyPrimitive; public SerializedMessage(string protocolName, System.ReadOnlyMemory<byte> serialized) { throw null; } - public string ProtocolName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public System.ReadOnlyMemory<byte> Serialized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public string ProtocolName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } + public System.ReadOnlyMemory<byte> Serialized { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } } public static partial class SignalRConnectionBuilderExtensions { diff --git a/src/SignalR/server/Core/src/DefaultHubLifetimeManager.cs b/src/SignalR/server/Core/src/DefaultHubLifetimeManager.cs index 3c835ab933..a8a9fe2095 100644 --- a/src/SignalR/server/Core/src/DefaultHubLifetimeManager.cs +++ b/src/SignalR/server/Core/src/DefaultHubLifetimeManager.cs @@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.SignalR return SendToAllConnections(methodName, args, null); } - private Task SendToAllConnections(string methodName, object[] args, Func<HubConnectionContext, bool> include) + private Task SendToAllConnections(string methodName, object[] args, Func<HubConnectionContext, object, bool> include, object state = null) { List<Task> tasks = null; SerializedHubMessage message = null; @@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.SignalR // foreach over HubConnectionStore avoids allocating an enumerator foreach (var connection in _connections) { - if (include != null && !include(connection)) + if (include != null && !include(connection, state)) { continue; } @@ -127,12 +127,12 @@ namespace Microsoft.AspNetCore.SignalR // Tasks and message are passed by ref so they can be lazily created inside the method post-filtering, // while still being re-usable when sending to multiple groups - private void SendToGroupConnections(string methodName, object[] args, ConcurrentDictionary<string, HubConnectionContext> connections, Func<HubConnectionContext, bool> include, ref List<Task> tasks, ref SerializedHubMessage message) + private void SendToGroupConnections(string methodName, object[] args, ConcurrentDictionary<string, HubConnectionContext> connections, Func<HubConnectionContext, object, bool> include, object state, ref List<Task> tasks, ref SerializedHubMessage message) { // foreach over ConcurrentDictionary avoids allocating an enumerator foreach (var connection in connections) { - if (include != null && !include(connection.Value)) + if (include != null && !include(connection.Value, state)) { continue; } @@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.SignalR // group might be modified inbetween checking and sending List<Task> tasks = null; SerializedHubMessage message = null; - SendToGroupConnections(methodName, args, group, null, ref tasks, ref message); + SendToGroupConnections(methodName, args, group, null, null, ref tasks, ref message); if (tasks != null) { @@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.SignalR var group = _groups[groupName]; if (group != null) { - SendToGroupConnections(methodName, args, group, null, ref tasks, ref message); + SendToGroupConnections(methodName, args, group, null, null, ref tasks, ref message); } } @@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.SignalR List<Task> tasks = null; SerializedHubMessage message = null; - SendToGroupConnections(methodName, args, group, connection => !excludedConnectionIds.Contains(connection.ConnectionId), ref tasks, ref message); + SendToGroupConnections(methodName, args, group, (connection, state) => !((IReadOnlyList<string>)state).Contains(connection.ConnectionId), excludedConnectionIds, ref tasks, ref message); if (tasks != null) { @@ -271,7 +271,7 @@ namespace Microsoft.AspNetCore.SignalR /// <inheritdoc /> public override Task SendUserAsync(string userId, string methodName, object[] args, CancellationToken cancellationToken = default) { - return SendToAllConnections(methodName, args, connection => string.Equals(connection.UserIdentifier, userId, StringComparison.Ordinal)); + return SendToAllConnections(methodName, args, (connection, state) => string.Equals(connection.UserIdentifier, (string)state, StringComparison.Ordinal), userId); } /// <inheritdoc /> @@ -292,19 +292,19 @@ namespace Microsoft.AspNetCore.SignalR /// <inheritdoc /> public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList<string> excludedConnectionIds, CancellationToken cancellationToken = default) { - return SendToAllConnections(methodName, args, connection => !excludedConnectionIds.Contains(connection.ConnectionId)); + return SendToAllConnections(methodName, args, (connection, state) => !((IReadOnlyList<string>)state).Contains(connection.ConnectionId), excludedConnectionIds); } /// <inheritdoc /> public override Task SendConnectionsAsync(IReadOnlyList<string> connectionIds, string methodName, object[] args, CancellationToken cancellationToken = default) { - return SendToAllConnections(methodName, args, connection => connectionIds.Contains(connection.ConnectionId)); + return SendToAllConnections(methodName, args, (connection, state) => ((IReadOnlyList<string>)state).Contains(connection.ConnectionId), connectionIds); } /// <inheritdoc /> public override Task SendUsersAsync(IReadOnlyList<string> userIds, string methodName, object[] args, CancellationToken cancellationToken = default) { - return SendToAllConnections(methodName, args, connection => userIds.Contains(connection.UserIdentifier)); + return SendToAllConnections(methodName, args, (connection, state) => ((IReadOnlyList<string>)state).Contains(connection.UserIdentifier), userIds); } } } diff --git a/src/SignalR/server/Core/src/HubClientsExtensions.cs b/src/SignalR/server/Core/src/HubClientsExtensions.cs index 8936bbc979..8f29cb89f3 100644 --- a/src/SignalR/server/Core/src/HubClientsExtensions.cs +++ b/src/SignalR/server/Core/src/HubClientsExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Linq; namespace Microsoft.AspNetCore.SignalR { @@ -126,6 +127,17 @@ namespace Microsoft.AspNetCore.SignalR return hubClients.AllExcept(new [] { excludedConnectionId1, excludedConnectionId2, excludedConnectionId3, excludedConnectionId4, excludedConnectionId5, excludedConnectionId6, excludedConnectionId7, excludedConnectionId8 }); } + /// <summary> + /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all clients connected to the hub excluding the specified connections. + /// </summary> + /// <param name="hubClients">The abstraction that provides access to connections.</param> + /// <param name="excludedConnectionIds">The connection IDs to exclude.</param> + /// <returns>A <typeparamref name="T" /> representing the methods that can be invoked on the clients.</returns> + public static T AllExcept<T>(this IHubClients<T> hubClients, IEnumerable<string> excludedConnectionIds) + { + return hubClients.AllExcept(excludedConnectionIds.ToList()); + } + /// <summary> /// Gets a <typeparamref name="T" /> that can be used to invoke methods on the specified connections. /// </summary> @@ -242,6 +254,17 @@ namespace Microsoft.AspNetCore.SignalR return hubClients.Clients(new [] { connection1, connection2, connection3, connection4, connection5, connection6, connection7, connection8 }); } + /// <summary> + /// Gets a <typeparamref name="T" /> that can be used to invoke methods on the specified connections. + /// </summary> + /// <param name="hubClients">The abstraction that provides access to connections.</param> + /// <param name="connectionIds">The connection IDs.</param> + /// <returns>A <typeparamref name="T" /> representing the methods that can be invoked on the clients.</returns> + public static T Clients<T>(this IHubClients<T> hubClients, IEnumerable<string> connectionIds) + { + return hubClients.Clients(connectionIds.ToList()); + } + /// <summary> /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all connections in all of the specified groups. /// </summary> @@ -358,6 +381,17 @@ namespace Microsoft.AspNetCore.SignalR return hubClients.Groups(new [] { group1, group2, group3, group4, group5, group6, group7, group8 }); } + /// <summary> + /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all connections in all of the specified groups. + /// </summary> + /// <param name="hubClients">The abstraction that provides access to connections.</param> + /// <param name="groupNames">The group names.</param> + /// <returns>A <typeparamref name="T" /> representing the methods that can be invoked on the clients.</returns> + public static T Groups<T>(this IHubClients<T> hubClients, IEnumerable<string> groupNames) + { + return hubClients.Groups(groupNames.ToList()); + } + /// <summary> /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all connections in the specified group excluding the specified connections. /// </summary> @@ -482,6 +516,18 @@ namespace Microsoft.AspNetCore.SignalR return hubClients.GroupExcept(groupName, new [] { excludedConnectionId1, excludedConnectionId2, excludedConnectionId3, excludedConnectionId4, excludedConnectionId5, excludedConnectionId6, excludedConnectionId7, excludedConnectionId8 }); } + /// <summary> + /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all connections in the specified group excluding the specified connections. + /// </summary> + /// <param name="hubClients">The abstraction that provides access to connections.</param> + /// <param name="groupName">The group name.</param> + /// <param name="excludedConnectionIds">The connection IDs to exclude.</param> + /// <returns>A <typeparamref name="T" /> representing the methods that can be invoked on the clients.</returns> + public static T GroupExcept<T>(this IHubClients<T> hubClients, string groupName, IEnumerable<string> excludedConnectionIds) + { + return hubClients.GroupExcept(groupName, excludedConnectionIds.ToList()); + } + /// <summary> /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all connections associated with all of the specified users. /// </summary> @@ -597,5 +643,16 @@ namespace Microsoft.AspNetCore.SignalR { return hubClients.Users(new [] { user1, user2, user3, user4, user5, user6, user7, user8 }); } + + /// <summary> + /// Gets a <typeparamref name="T" /> that can be used to invoke methods on all connections associated with all of the specified users. + /// </summary> + /// <param name="hubClients">The abstraction that provides access to connections.</param> + /// <param name="userIds">The user IDs.</param> + /// <returns>A <typeparamref name="T" /> representing the methods that can be invoked on the clients.</returns> + public static T Users<T>(this IHubClients<T> hubClients, IEnumerable<string> userIds) + { + return hubClients.Users(userIds.ToList()); + } } } diff --git a/src/SignalR/server/Core/src/HubConnectionContext.cs b/src/SignalR/server/Core/src/HubConnectionContext.cs index 8e9216d35d..bd544102c0 100644 --- a/src/SignalR/server/Core/src/HubConnectionContext.cs +++ b/src/SignalR/server/Core/src/HubConnectionContext.cs @@ -564,6 +564,11 @@ namespace Microsoft.AspNetCore.SignalR private void CheckClientTimeout() { + if (Debugger.IsAttached) + { + return; + } + // If it's been too long since we've heard from the client, then close this if (DateTime.UtcNow.Ticks - Volatile.Read(ref _lastReceivedTimeStamp) > _clientTimeoutInterval) { diff --git a/src/SignalR/server/Core/src/HubInvocationContext.cs b/src/SignalR/server/Core/src/HubInvocationContext.cs index a62706d6a8..967db6ebb5 100644 --- a/src/SignalR/server/Core/src/HubInvocationContext.cs +++ b/src/SignalR/server/Core/src/HubInvocationContext.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using Microsoft.AspNetCore.Authorization; @@ -11,6 +12,18 @@ namespace Microsoft.AspNetCore.SignalR /// </summary> public class HubInvocationContext { + /// <summary> + /// Instantiates a new instance of the <see cref="HubInvocationContext"/> class. + /// </summary> + /// <param name="context">Context for the active Hub connection and caller.</param> + /// <param name="hubType">The type of the Hub.</param> + /// <param name="hubMethodName">The name of the Hub method being invoked.</param> + /// <param name="hubMethodArguments">The arguments provided by the client.</param> + public HubInvocationContext(HubCallerContext context, Type hubType, string hubMethodName, object[] hubMethodArguments): this(context, hubMethodName, hubMethodArguments) + { + HubType = hubType; + } + /// <summary> /// Instantiates a new instance of the <see cref="HubInvocationContext"/> class. /// </summary> @@ -29,6 +42,11 @@ namespace Microsoft.AspNetCore.SignalR /// </summary> public HubCallerContext Context { get; } + /// <summary> + /// Gets the Hub type. + /// </summary> + public Type HubType { get; } + /// <summary> /// Gets the name of the Hub method being invoked. /// </summary> diff --git a/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs b/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs index 1f5faf714d..74d7fe27ca 100644 --- a/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs +++ b/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs @@ -275,7 +275,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal { if (descriptor.OriginalParameterTypes[parameterPointer] == typeof(CancellationToken)) { - cts = CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAborted); + cts = CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAborted, default); arguments[parameterPointer] = cts.Token; } else if (isStreamCall && ReflectionHelper.IsStreamingType(descriptor.OriginalParameterTypes[parameterPointer], mustBeDirectType: true)) @@ -308,7 +308,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal return; } - cts = cts ?? CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAborted); + cts = cts ?? CancellationTokenSource.CreateLinkedTokenSource(connection.ConnectionAborted, default); connection.ActiveRequestCancellationSources.TryAdd(hubMethodInvocationMessage.InvocationId, cts); var enumerable = descriptor.FromReturnedStream(result, cts.Token); @@ -489,12 +489,12 @@ namespace Microsoft.AspNetCore.SignalR.Internal private Task<bool> IsHubMethodAuthorized(IServiceProvider provider, HubConnectionContext hubConnectionContext, IList<IAuthorizeData> policies, string hubMethodName, object[] hubMethodArguments) { // If there are no policies we don't need to run auth - if (!policies.Any()) + if (policies.Count == 0) { return TaskCache.True; } - return IsHubMethodAuthorizedSlow(provider, hubConnectionContext.User, policies, new HubInvocationContext(hubConnectionContext.HubCallerContext, hubMethodName, hubMethodArguments)); + return IsHubMethodAuthorizedSlow(provider, hubConnectionContext.User, policies, new HubInvocationContext(hubConnectionContext.HubCallerContext, typeof(THub), hubMethodName, hubMethodArguments)); } private static async Task<bool> IsHubMethodAuthorizedSlow(IServiceProvider provider, ClaimsPrincipal principal, IList<IAuthorizeData> policies, HubInvocationContext resource) @@ -547,6 +547,11 @@ namespace Microsoft.AspNetCore.SignalR.Internal foreach (var methodInfo in HubReflectionHelper.GetHubMethods(hubType)) { + if (methodInfo.IsGenericMethod) + { + throw new NotSupportedException($"Method '{methodInfo.Name}' is a generic method which is not supported on a Hub."); + } + var methodName = methodInfo.GetCustomAttribute<HubMethodNameAttribute>()?.Name ?? methodInfo.Name; diff --git a/src/SignalR/server/Core/src/Internal/TypedClientBuilder.cs b/src/SignalR/server/Core/src/Internal/TypedClientBuilder.cs index 511280d636..b0343577cb 100644 --- a/src/SignalR/server/Core/src/Internal/TypedClientBuilder.cs +++ b/src/SignalR/server/Core/src/Internal/TypedClientBuilder.cs @@ -20,6 +20,10 @@ namespace Microsoft.AspNetCore.SignalR.Internal private static readonly PropertyInfo CancellationTokenNoneProperty = typeof(CancellationToken).GetProperty("None", BindingFlags.Public | BindingFlags.Static); + private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructors().Single(); + + private static readonly Type[] ParameterTypes = new Type[] { typeof(IClientProxy) }; + public static T Build(IClientProxy proxy) { return _builder.Value(proxy); @@ -40,20 +44,24 @@ namespace Microsoft.AspNetCore.SignalR.Internal var moduleBuilder = assemblyBuilder.DefineDynamicModule(ClientModuleName); var clientType = GenerateInterfaceImplementation(moduleBuilder); - return proxy => (T)Activator.CreateInstance(clientType, proxy); + var factoryMethod = clientType.GetMethod(nameof(Build), BindingFlags.Public | BindingFlags.Static); + return (Func<IClientProxy, T>)factoryMethod.CreateDelegate(typeof(Func<IClientProxy, T>)); } private static Type GenerateInterfaceImplementation(ModuleBuilder moduleBuilder) { - var type = moduleBuilder.DefineType( - ClientModuleName + "." + typeof(T).Name + "Impl", - TypeAttributes.Public, - typeof(Object), - new[] { typeof(T) }); + var name = ClientModuleName + "." + typeof(T).Name + "Impl"; - var proxyField = type.DefineField("_proxy", typeof(IClientProxy), FieldAttributes.Private); + var type = moduleBuilder.DefineType(name, TypeAttributes.Public, typeof(object), new[] { typeof(T) }); - BuildConstructor(type, proxyField); + var proxyField = type.DefineField("_proxy", typeof(IClientProxy), FieldAttributes.Private | FieldAttributes.InitOnly); + + var ctor = BuildConstructor(type, proxyField); + + // Because a constructor doesn't return anything, it can't be wrapped in a + // delegate directly, so we emit a factory method that just takes the IClientProxy, + // invokes the constructor (using newobj) and returns the new instance of type T. + BuildFactoryMethod(type, ctor); foreach (var method in GetAllInterfaceMethods(typeof(T))) { @@ -79,27 +87,23 @@ namespace Microsoft.AspNetCore.SignalR.Internal } } - private static void BuildConstructor(TypeBuilder type, FieldInfo proxyField) + private static ConstructorInfo BuildConstructor(TypeBuilder type, FieldInfo proxyField) { - var method = type.DefineMethod(".ctor", System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.HideBySig); + var ctor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ParameterTypes); - var ctor = typeof(object).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, - null, new Type[] { }, null); - - method.SetReturnType(typeof(void)); - method.SetParameters(typeof(IClientProxy)); - - var generator = method.GetILGenerator(); + var generator = ctor.GetILGenerator(); // Call object constructor generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Call, ctor); + generator.Emit(OpCodes.Call, ObjectConstructor); // Assign constructor argument to the proxyField generator.Emit(OpCodes.Ldarg_0); // type generator.Emit(OpCodes.Ldarg_1); // type proxyfield generator.Emit(OpCodes.Stfld, proxyField); // type.proxyField = proxyField generator.Emit(OpCodes.Ret); + + return ctor; } private static void BuildMethod(TypeBuilder type, MethodInfo interfaceMethodInfo, FieldInfo proxyField) @@ -127,11 +131,19 @@ namespace Microsoft.AspNetCore.SignalR.Internal var genericTypeNames = paramTypes.Where(p => p.IsGenericParameter).Select(p => p.Name).Distinct().ToArray(); - if (genericTypeNames.Any()) + if (genericTypeNames.Length > 0) { methodBuilder.DefineGenericParameters(genericTypeNames); } + // Check to see if the last parameter of the method is a CancellationToken + bool hasCancellationToken = paramTypes.LastOrDefault() == typeof(CancellationToken); + if (hasCancellationToken) + { + // remove CancellationToken from input paramTypes + paramTypes = paramTypes.Take(paramTypes.Length - 1).ToArray(); + } + var generator = methodBuilder.GetILGenerator(); // Declare local variable to store the arguments to IClientProxy.SendCoreAsync @@ -145,7 +157,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal generator.Emit(OpCodes.Ldstr, interfaceMethodInfo.Name); // Create an new object array to hold all the parameters to this method - generator.Emit(OpCodes.Ldc_I4, parameters.Length); // Stack: + generator.Emit(OpCodes.Ldc_I4, paramTypes.Length); // Stack: generator.Emit(OpCodes.Newarr, typeof(object)); // allocate object array generator.Emit(OpCodes.Stloc_0); @@ -162,8 +174,16 @@ namespace Microsoft.AspNetCore.SignalR.Internal // Load parameter array on to the stack. generator.Emit(OpCodes.Ldloc_0); - // Get 'CancellationToken.None' and put it on the stack, since we don't support CancellationToken right now - generator.Emit(OpCodes.Call, CancellationTokenNoneProperty.GetMethod); + if (hasCancellationToken) + { + // Get CancellationToken from input argument and put it on the stack + generator.Emit(OpCodes.Ldarg, paramTypes.Length + 1); + } + else + { + // Get 'CancellationToken.None' and put it on the stack, for when method does not have CancellationToken + generator.Emit(OpCodes.Call, CancellationTokenNoneProperty.GetMethod); + } // Send! generator.Emit(OpCodes.Callvirt, invokeMethod); @@ -171,6 +191,17 @@ namespace Microsoft.AspNetCore.SignalR.Internal generator.Emit(OpCodes.Ret); // Return the Task returned by 'invokeMethod' } + private static void BuildFactoryMethod(TypeBuilder type, ConstructorInfo ctor) + { + var method = type.DefineMethod(nameof(Build), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(T), ParameterTypes); + + var generator = method.GetILGenerator(); + + generator.Emit(OpCodes.Ldarg_0); // Load the IClientProxy argument onto the stack + generator.Emit(OpCodes.Newobj, ctor); // Call the generated constructor with the proxy + generator.Emit(OpCodes.Ret); // Return the typed client + } + private static void VerifyInterface(Type interfaceType) { if (!interfaceType.IsInterface) @@ -190,7 +221,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal foreach (var method in interfaceType.GetMethods()) { - VerifyMethod(interfaceType, method); + VerifyMethod(method); } foreach (var parent in interfaceType.GetInterfaces()) @@ -199,7 +230,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal } } - private static void VerifyMethod(Type interfaceType, MethodInfo interfaceMethod) + private static void VerifyMethod(MethodInfo interfaceMethod) { if (interfaceMethod.ReturnType != typeof(Task)) { diff --git a/src/SignalR/server/SignalR/test/HubConnectionHandlerTestUtils/Hubs.cs b/src/SignalR/server/SignalR/test/HubConnectionHandlerTestUtils/Hubs.cs index 3cae11661a..c9fc9e96ba 100644 --- a/src/SignalR/server/SignalR/test/HubConnectionHandlerTestUtils/Hubs.cs +++ b/src/SignalR/server/SignalR/test/HubConnectionHandlerTestUtils/Hubs.cs @@ -569,6 +569,13 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + public class GenericMethodHub : Hub + { + public void GenericMethod<T>() + { + } + } + public class DisposeTrackingHub : TestHub { private readonly TrackDispose _trackDispose; diff --git a/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs b/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs index 9f727d6523..3d9c97c1ac 100644 --- a/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs +++ b/src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs @@ -1327,6 +1327,19 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public void CannotHaveGenericMethodOnHub() + { + using (StartVerifiableLog()) + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(null, LoggerFactory); + + var exception = Assert.Throws<NotSupportedException>(() => serviceProvider.GetService<HubConnectionHandler<GenericMethodHub>>()); + + Assert.Equal("Method 'GenericMethod' is a generic method which is not supported on a Hub.", exception.Message); + } + } + [Theory] [MemberData(nameof(HubTypes))] public async Task BroadcastHubMethodSendsToAllClients(Type hubType) @@ -2215,6 +2228,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests { Assert.NotNull(context.Resource); var resource = Assert.IsType<HubInvocationContext>(context.Resource); + Assert.Equal(typeof(MethodHub), resource.HubType); Assert.Equal(nameof(MethodHub.MultiParamAuthMethod), resource.HubMethodName); Assert.Equal(2, resource.HubMethodArguments?.Count); Assert.Equal("Hello", resource.HubMethodArguments[0]); @@ -3739,7 +3753,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests // The usage of TypeNameHandling.All is a security risk. // If you're implementing this in your own application instead use your own 'type' field and a custom JsonConverter // or ensure you're restricting to only known types with a custom SerializationBinder like we are here. - // See https://github.com/aspnet/AspNetCore/issues/11495#issuecomment-505047422 + // See https://github.com/dotnet/aspnetcore/issues/11495#issuecomment-505047422 TypeNameHandling = TypeNameHandling.All, SerializationBinder = StreamingHub.DerivedParameterKnownTypesBinder.Instance } diff --git a/src/SignalR/server/SignalR/test/Internal/TypedClientBuilderTests.cs b/src/SignalR/server/SignalR/test/Internal/TypedClientBuilderTests.cs index 4f68f6fe74..f88820cb78 100644 --- a/src/SignalR/server/SignalR/test/Internal/TypedClientBuilderTests.cs +++ b/src/SignalR/server/SignalR/test/Internal/TypedClientBuilderTests.cs @@ -75,6 +75,41 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal await task2.OrTimeout(); } + [Fact] + public async Task SupportsCancellationToken() + { + var clientProxy = new MockProxy(); + var typedProxy = TypedClientBuilder<ICancellationTokenMethod>.Build(clientProxy); + CancellationTokenSource cts1 = new CancellationTokenSource(); + var task1 = typedProxy.Method("foo", cts1.Token); + Assert.False(task1.IsCompleted); + + CancellationTokenSource cts2 = new CancellationTokenSource(); + var task2 = typedProxy.NoArgumentMethod(cts2.Token); + Assert.False(task2.IsCompleted); + + Assert.Collection(clientProxy.Sends, + send1 => + { + Assert.Equal("Method", send1.Method); + Assert.Single(send1.Arguments); + Assert.Collection(send1.Arguments, + arg1 => Assert.Equal("foo", arg1)); + Assert.Equal(cts1.Token, send1.CancellationToken); + send1.Complete(); + }, + send2 => + { + Assert.Equal("NoArgumentMethod", send2.Method); + Assert.Empty(send2.Arguments); + Assert.Equal(cts2.Token, send2.CancellationToken); + send2.Complete(); + }); + + await task1.OrTimeout(); + await task2.OrTimeout(); + } + [Fact] public void ThrowsIfProvidedAClass() { @@ -179,6 +214,12 @@ namespace Microsoft.AspNetCore.SignalR.Tests.Internal Task SubMethod(string foo); } + public interface ICancellationTokenMethod + { + Task Method(string foo, CancellationToken cancellationToken); + Task NoArgumentMethod(CancellationToken cancellationToken); + } + public interface IPropertiesClient { string Property { get; } diff --git a/src/SignalR/server/SignalR/test/UserAgentHeaderTest.cs b/src/SignalR/server/SignalR/test/UserAgentHeaderTest.cs new file mode 100644 index 0000000000..f1371b42cd --- /dev/null +++ b/src/SignalR/server/SignalR/test/UserAgentHeaderTest.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using Microsoft.AspNetCore.Http.Connections.Client; +using Xunit; +using Constants = Microsoft.AspNetCore.Http.Connections.Client.Internal.Constants; + +namespace Microsoft.AspNetCore.Http.Connections.Tests +{ + public class UserAgentHeaderTest + { + [Theory] + [MemberData(nameof(UserAgents))] + public void UserAgentHeaderIsCorrect(Version version, string detailedVersion, string os, string runtime, string runtimeVersion, string expected) + { + Assert.Equal(expected, Constants.ConstructUserAgent(version, detailedVersion, os, runtime, runtimeVersion)); + } + + public static IEnumerable<object[]> UserAgents() + { + yield return new object[] { new Version(1, 4), "1.4.3-preview9", "Windows NT", ".NET", ".NET 4.8.7", "Microsoft SignalR/1.4 (1.4.3-preview9; Windows NT; .NET; .NET 4.8.7)" }; + yield return new object[] { new Version(3, 1), "3.1.0", "", ".NET", ".NET 4.8.9", "Microsoft SignalR/3.1 (3.1.0; Unknown OS; .NET; .NET 4.8.9)" }; + yield return new object[] { new Version(3, 1), "3.1.0", "", ".NET", "", "Microsoft SignalR/3.1 (3.1.0; Unknown OS; .NET; Unknown Runtime Version)" }; + yield return new object[] { new Version(3, 1), "", "Linux", ".NET", ".NET 4.5.1", "Microsoft SignalR/3.1 (Unknown Version; Linux; .NET; .NET 4.5.1)" }; + } + } +} diff --git a/src/SignalR/server/Specification.Tests/src/Internal/TaskExtensions.cs b/src/SignalR/server/Specification.Tests/src/Internal/TaskExtensions.cs index 1a6b2a7485..7b431133c5 100644 --- a/src/SignalR/server/Specification.Tests/src/Internal/TaskExtensions.cs +++ b/src/SignalR/server/Specification.Tests/src/Internal/TaskExtensions.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace Microsoft.AspNetCore.Testing { - // Copied from https://github.com/aspnet/Extensions/blob/master/src/TestingUtils/Microsoft.AspNetCore.Testing/src/TaskExtensions.cs + // Copied from https://github.com/dotnet/extensions/blob/master/src/TestingUtils/Microsoft.AspNetCore.Testing/src/TaskExtensions.cs // Required because Microsoft.AspNetCore.Testing is not shipped internal static class TaskExtensions { diff --git a/src/SignalR/server/StackExchangeRedis/ref/Microsoft.AspNetCore.SignalR.StackExchangeRedis.netcoreapp.cs b/src/SignalR/server/StackExchangeRedis/ref/Microsoft.AspNetCore.SignalR.StackExchangeRedis.netcoreapp.cs index 8de5c13646..b71edc2199 100644 --- a/src/SignalR/server/StackExchangeRedis/ref/Microsoft.AspNetCore.SignalR.StackExchangeRedis.netcoreapp.cs +++ b/src/SignalR/server/StackExchangeRedis/ref/Microsoft.AspNetCore.SignalR.StackExchangeRedis.netcoreapp.cs @@ -26,8 +26,8 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis public partial class RedisOptions { public RedisOptions() { } - public StackExchange.Redis.ConfigurationOptions Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } - public System.Func<System.IO.TextWriter, System.Threading.Tasks.Task<StackExchange.Redis.IConnectionMultiplexer>> ConnectionFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } + public StackExchange.Redis.ConfigurationOptions Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } + public System.Func<System.IO.TextWriter, System.Threading.Tasks.Task<StackExchange.Redis.IConnectionMultiplexer>> ConnectionFactory { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } } } namespace Microsoft.Extensions.DependencyInjection diff --git a/src/SignalR/server/StackExchangeRedis/src/Internal/RedisProtocol.cs b/src/SignalR/server/StackExchangeRedis/src/Internal/RedisProtocol.cs index 76b5ed1b6e..2442618489 100644 --- a/src/SignalR/server/StackExchangeRedis/src/Internal/RedisProtocol.cs +++ b/src/SignalR/server/StackExchangeRedis/src/Internal/RedisProtocol.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.SignalR.StackExchangeRedis.Internal // * Acks are sent to the Acknowledgement channel. // * See the Write[type] methods for a description of the protocol for each in-depth. // * The "Variable length integer" is the length-prefixing format used by BinaryReader/BinaryWriter: - // * https://docs.microsoft.com/en-us/dotnet/api/system.io.binarywriter.write?view=netstandard-2.0 + // * https://docs.microsoft.com/dotnet/api/system.io.binarywriter.write?view=netcore-2.2 // * The "Length prefixed string" is the string format used by BinaryReader/BinaryWriter: // * A 7-bit variable length integer encodes the length in bytes, followed by the encoded string in UTF-8. diff --git a/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj b/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj index 4ef7283db6..82e665d1c0 100644 --- a/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj +++ b/src/SiteExtensions/LoggingAggregate/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj @@ -24,6 +24,8 @@ <ItemGroup> <Reference Include="Microsoft.AspNetCore.AzureAppServices.SiteExtension.2.1" Version="$(MicrosoftAspNetCoreAzureAppServicesSiteExtension21PackageVersion)" PrivateAssets="All" /> <Reference Include="Microsoft.AspNetCore.AzureAppServices.SiteExtension.2.2" Version="$(MicrosoftAspNetCoreAzureAppServicesSiteExtension22PackageVersion)" PrivateAssets="All" /> + <PackageReference Include="Microsoft.AspNetCore.AzureAppServices.SiteExtension.5.0.x86" Version="$(PackageVersion)" PrivateAssets="All" /> + <PackageReference Include="Microsoft.AspNetCore.AzureAppServices.SiteExtension.5.0.x64" Version="$(PackageVersion)" PrivateAssets="All" /> </ItemGroup> <ItemGroup> diff --git a/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs b/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs index c7d2d13e49..347c0d82ee 100644 --- a/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs +++ b/src/Tools/Extensions.ApiDescription.Client/src/CSharpIdentifier.cs @@ -5,7 +5,7 @@ using System.Globalization; using System.Text; // Copied from -// https://github.com/aspnet/AspNetCore-Tooling/blob/master/src/Razor/src/Microsoft.AspNetCore.Razor.Language/CSharpIdentifier.cs +// https://github.com/dotnet/aspnetcore-tooling/blob/master/src/Razor/src/Microsoft.AspNetCore.Razor.Language/CSharpIdentifier.cs namespace Microsoft.Extensions.ApiDescription.Client { internal static class CSharpIdentifier diff --git a/src/Tools/FirstRunCertGenerator/test/CertificateManagerTests.cs b/src/Tools/FirstRunCertGenerator/test/CertificateManagerTests.cs index a0f103342a..5e131c2afd 100644 --- a/src/Tools/FirstRunCertGenerator/test/CertificateManagerTests.cs +++ b/src/Tools/FirstRunCertGenerator/test/CertificateManagerTests.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation.Tests public ITestOutputHelper Output { get; } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6721")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6721")] public void EnsureCreateHttpsCertificate_CreatesACertificate_WhenThereAreNoHttpsCertificates() { try @@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation.Tests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6721")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6721")] public void EnsureCreateHttpsCertificate_DoesNotCreateACertificate_WhenThereIsAnExistingHttpsCertificates() { // Arrange @@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation.Tests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6721")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6721")] public void EnsureCreateHttpsCertificate_ReturnsExpiredCertificateIfVersionIsIncorrect() { _fixture.CleanupCertificates(); @@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation.Tests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6721")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6721")] public void EnsureCreateHttpsCertificate_ReturnsExpiredCertificateForEmptyVersionField() { _fixture.CleanupCertificates(); @@ -188,7 +188,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation.Tests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6721")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6721")] public void EnsureCreateHttpsCertificate_ReturnsValidIfVersionIsZero() { _fixture.CleanupCertificates(); @@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.Certificates.Generation.Tests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/6721")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6721")] public void EnsureCreateHttpsCertificate_ReturnValidIfCertIsNewer() { _fixture.CleanupCertificates(); diff --git a/src/Tools/Microsoft.dotnet-openapi/README.md b/src/Tools/Microsoft.dotnet-openapi/README.md index 9ad333bddc..e5c004c2a5 100644 --- a/src/Tools/Microsoft.dotnet-openapi/README.md +++ b/src/Tools/Microsoft.dotnet-openapi/README.md @@ -6,14 +6,13 @@ ### Add Commands -<!-- TODO: Restore after https://github.com/aspnet/AspNetCore/issues/12738 +<!-- TODO: Restore after https://github.com/dotnet/aspnetcore/issues/12738 #### Add Project ##### Options | Short option | Long option | Description | Example | |-------|------|-------|---------| -| -v|--verbose | Show verbose output. |dotnet openapi add project *-v* ../Ref/ProjRef.csproj | | -p|--project | The project to operate on. |dotnet openapi add project *--project .\Ref.csproj* ../Ref/ProjRef.csproj | ##### Arguments @@ -28,7 +27,6 @@ | Short option| Long option| Description | Example | |-------|------|-------|---------| -| -v|--verbose | Show verbose output. |dotnet openapi add file *-v* .\OpenAPI.json | | -p|--updateProject | The project to operate on. |dotnet openapi add file *--updateProject .\Ref.csproj* .\OpenAPI.json | ##### Arguments @@ -43,7 +41,6 @@ | Short option| Long option| Description | Example | |-------|------|-------------|---------| -| -v|--verbose | Show verbose output. |dotnet openapi add url *-v* <http://contoso.com/openapi.json> | | -p|--updateProject | The project to operate on. |dotnet openapi add url *--updateProject .\Ref.csproj* <http://contoso.com/openapi.json> | | -o|--output-file | Where to place the local copy of the OpenAPI file. |dotnet openapi add url <https://contoso.com/openapi.json> *--output-file myclient.json* | @@ -59,7 +56,6 @@ | Short option| Long option| Description| Example | |-------|------|------------|---------| -| -v|--verbose | Show verbose output. |dotnet openapi remove *-v*| | -p|--updateProject | The project to operate on. |dotnet openapi remove *--updateProject .\Ref.csproj* .\OpenAPI.json | #### Arguments @@ -74,7 +70,6 @@ | Short option| Long option| Description | Example | |-------|------|-------------|---------| -| -v|--verbose | Show verbose output. | dotnet openapi refresh *-v* <https://contoso.com/openapi.json> | | -p|--updateProject | The project to operate on. | dotnet openapi refresh *--updateProject .\Ref.csproj* <https://contoso.com/openapi.json> | #### Arguments diff --git a/src/Tools/Microsoft.dotnet-openapi/src/Commands/AddCommand.cs b/src/Tools/Microsoft.dotnet-openapi/src/Commands/AddCommand.cs index bf879c8b20..1abe244b90 100644 --- a/src/Tools/Microsoft.dotnet-openapi/src/Commands/AddCommand.cs +++ b/src/Tools/Microsoft.dotnet-openapi/src/Commands/AddCommand.cs @@ -14,7 +14,7 @@ namespace Microsoft.DotNet.OpenApi.Commands : base(parent, CommandName, httpClient) { Commands.Add(new AddFileCommand(this, httpClient)); - //TODO: Add AddprojectComand here: https://github.com/aspnet/AspNetCore/issues/12738 + //TODO: Add AddprojectComand here: https://github.com/dotnet/aspnetcore/issues/12738 Commands.Add(new AddURLCommand(this, httpClient)); } diff --git a/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs b/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs index 92fe39df4f..88cc458a1f 100644 --- a/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs +++ b/src/Tools/Microsoft.dotnet-openapi/src/Commands/BaseCommand.cs @@ -159,7 +159,7 @@ namespace Microsoft.DotNet.OpenApi.Commands var items = project.GetItems(tagName); var fileItems = items.Where(i => string.Equals(GetFullPath(i.EvaluatedInclude), GetFullPath(sourceFile), StringComparison.Ordinal)); - if (fileItems.Count() > 0) + if (fileItems.Any()) { Warning.Write($"One or more references to {sourceFile} already exist in '{project.FullPath}'. Duplicate references could lead to unexpected behavior."); return; @@ -200,44 +200,52 @@ namespace Microsoft.DotNet.OpenApi.Commands var packageId = kvp.Key; var version = urlPackages != null && urlPackages.ContainsKey(packageId) ? urlPackages[packageId] : kvp.Value; - var args = new[] { - "add", - "package", - packageId, - "--version", - version, - "--no-restore" - }; + await TryAddPackage(packageId, version, projectFile); + } + } - var muxer = DotNetMuxer.MuxerPathOrDefault(); - if (string.IsNullOrEmpty(muxer)) - { - throw new ArgumentException($"dotnet was not found on the path."); - } + private async Task TryAddPackage(string packageId, string packageVersion, FileInfo projectFile) + { + var args = new[] { + "add", + "package", + packageId, + "--version", + packageVersion, + "--no-restore" + }; - var startInfo = new ProcessStartInfo - { - FileName = muxer, - Arguments = string.Join(" ", args), - WorkingDirectory = projectFile.Directory.FullName, - RedirectStandardError = true, - RedirectStandardOutput = true, - }; + var muxer = DotNetMuxer.MuxerPathOrDefault(); + if (string.IsNullOrEmpty(muxer)) + { + throw new ArgumentException($"dotnet was not found on the path."); + } - var process = Process.Start(startInfo); + var startInfo = new ProcessStartInfo + { + FileName = muxer, + Arguments = string.Join(" ", args), + WorkingDirectory = projectFile.Directory.FullName, + RedirectStandardError = true, + RedirectStandardOutput = true, + }; - var timeout = 20; - if (!process.WaitForExit(timeout * 1000)) - { - throw new ArgumentException($"Adding package `{packageId}` to `{projectFile.Directory}` took longer than {timeout} seconds."); - } + using var process = Process.Start(startInfo); - if (process.ExitCode != 0) - { - Out.Write(process.StandardOutput.ReadToEnd()); - Error.Write(process.StandardError.ReadToEnd()); - throw new ArgumentException($"Could not add package `{packageId}` to `{projectFile.Directory}`"); - } + var timeout = 20; + if (!process.WaitForExit(timeout * 1000)) + { + throw new ArgumentException($"Adding package `{packageId}` to `{projectFile.Directory}` took longer than {timeout} seconds."); + } + + if (process.ExitCode != 0) + { + var output = await process.StandardOutput.ReadToEndAsync(); + var error = await process.StandardError.ReadToEndAsync(); + await Out.WriteAsync(output); + await Error.WriteAsync(error); + + throw new ArgumentException($"Could not add package `{packageId}` to `{projectFile.Directory}` due to: `{error}`"); } } @@ -368,7 +376,7 @@ namespace Microsoft.DotNet.OpenApi.Commands else { var uri = new Uri(url); - if (uri.Segments.Count() > 0 && uri.Segments.Last() != "/") + if (uri.Segments.Any() && uri.Segments.Last() != "/") { var lastSegment = uri.Segments.Last(); if (!Path.HasExtension(lastSegment)) diff --git a/src/Tools/Microsoft.dotnet-openapi/test/OpenApiAddProjectTests.cs b/src/Tools/Microsoft.dotnet-openapi/test/OpenApiAddProjectTests.cs index 2069b426c1..691b0fc8f2 100644 --- a/src/Tools/Microsoft.dotnet-openapi/test/OpenApiAddProjectTests.cs +++ b/src/Tools/Microsoft.dotnet-openapi/test/OpenApiAddProjectTests.cs @@ -15,7 +15,7 @@ namespace Microsoft.DotNet.OpenApi.Add.Tests { public OpenApiAddProjectTests(ITestOutputHelper output) : base(output){} - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12738")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")] public async Task OpenApi_Add_GlobbingOpenApi() { var project = CreateBasicProject(withOpenApi: true); @@ -54,7 +54,7 @@ namespace Microsoft.DotNet.OpenApi.Add.Tests } } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12738")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")] public void OpenApi_Add_Project_EquivilentPaths() { var project = CreateBasicProject(withOpenApi: false); @@ -88,7 +88,7 @@ namespace Microsoft.DotNet.OpenApi.Add.Tests } } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12738")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")] public async Task OpenApi_Add_FromCsProj() { var project = CreateBasicProject(withOpenApi: false); diff --git a/src/Tools/Microsoft.dotnet-openapi/test/OpenApiRemoveTests.cs b/src/Tools/Microsoft.dotnet-openapi/test/OpenApiRemoveTests.cs index 71bd578324..635cb4f766 100644 --- a/src/Tools/Microsoft.dotnet-openapi/test/OpenApiRemoveTests.cs +++ b/src/Tools/Microsoft.dotnet-openapi/test/OpenApiRemoveTests.cs @@ -103,7 +103,7 @@ namespace Microsoft.DotNet.OpenApi.Remove.Tests Assert.DoesNotContain($"<OpenApiReference", removedContent); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/12738")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/12738")] public async Task OpenApi_Remove_Project() { _tempDir diff --git a/src/Tools/Microsoft.dotnet-openapi/test/OpenApiTestBase.cs b/src/Tools/Microsoft.dotnet-openapi/test/OpenApiTestBase.cs index d230e1bb8d..7e33386d27 100644 --- a/src/Tools/Microsoft.dotnet-openapi/test/OpenApiTestBase.cs +++ b/src/Tools/Microsoft.dotnet-openapi/test/OpenApiTestBase.cs @@ -21,8 +21,7 @@ namespace Microsoft.DotNet.OpenApi.Tests protected readonly TextWriter _output = new StringWriter(); protected readonly TextWriter _error = new StringWriter(); protected readonly ITestOutputHelper _outputHelper; - protected const string TestTFM = "netcoreapp3.1"; - + protected const string TestTFM = "netcoreapp5.0"; protected const string Content = @"{""x-generator"": ""NSwag""}"; protected const string ActualUrl = "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/api-with-examples.yaml"; diff --git a/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj b/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj index 6f7a08de47..6fc54a7a87 100644 --- a/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj +++ b/src/Tools/dotnet-sql-cache/src/dotnet-sql-cache.csproj @@ -17,7 +17,7 @@ <Reference Include="Microsoft.Extensions.CommandLineUtils.Sources" /> <Reference Include="Microsoft.Data.SqlClient" /> - <!-- Intentional change to remove reference to System.Data.SqlClient. See https://github.com/aspnet/AspNetCore/issues/12445 --> + <!-- Intentional change to remove reference to System.Data.SqlClient. See https://github.com/dotnet/aspnetcore/issues/12445 --> <SuppressBaselineReference Include="System.Data.SqlClient" /> </ItemGroup> diff --git a/src/Tools/dotnet-user-secrets/test/UserSecretsTestFixture.cs b/src/Tools/dotnet-user-secrets/test/UserSecretsTestFixture.cs index adcbe32b1e..5a42903675 100644 --- a/src/Tools/dotnet-user-secrets/test/UserSecretsTestFixture.cs +++ b/src/Tools/dotnet-user-secrets/test/UserSecretsTestFixture.cs @@ -35,7 +35,7 @@ namespace Microsoft.Extensions.Configuration.UserSecrets.Tests private const string ProjectTemplate = @"<Project ToolsVersion=""15.0"" Sdk=""Microsoft.NET.Sdk""> <PropertyGroup> <OutputType>Exe</OutputType> - <TargetFrameworks>netcoreapp3.1</TargetFrameworks> + <TargetFrameworks>netcoreapp5.0</TargetFrameworks> {0} <EnableDefaultCompileItems>false</EnableDefaultCompileItems> </PropertyGroup> diff --git a/src/Tools/dotnet-watch/test/AppWithDepsTests.cs b/src/Tools/dotnet-watch/test/AppWithDepsTests.cs index 9888258327..a14e8c6c05 100644 --- a/src/Tools/dotnet-watch/test/AppWithDepsTests.cs +++ b/src/Tools/dotnet-watch/test/AppWithDepsTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests _app = new AppWithDeps(logger); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8267")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/8267")] public async Task ChangeFileInDependency() { await _app.StartWatcherAsync(); diff --git a/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs b/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs index d6e57ee5cf..234da30140 100644 --- a/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs +++ b/src/Tools/dotnet-watch/test/DotNetWatcherTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/8267")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/8267")] public async Task RunsWithDotnetWatchEnvVariable() { Assert.True(string.IsNullOrEmpty(Environment.GetEnvironmentVariable("DOTNET_WATCH")), "DOTNET_WATCH cannot be set already when this test is running"); diff --git a/src/Tools/dotnet-watch/test/GlobbingAppTests.cs b/src/Tools/dotnet-watch/test/GlobbingAppTests.cs index 8667c06e7d..6cde7bbf5d 100644 --- a/src/Tools/dotnet-watch/test/GlobbingAppTests.cs +++ b/src/Tools/dotnet-watch/test/GlobbingAppTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests _app = new GlobbingApp(logger); } - [Theory(Skip = "https://github.com/aspnet/AspNetCore/issues/8267")] + [Theory(Skip = "https://github.com/dotnet/aspnetcore/issues/8267")] [InlineData(true)] [InlineData(false)] public async Task ChangeCompiledFile(bool usePollingWatcher) @@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests Assert.Equal(2, types); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8267")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/8267")] public async Task DeleteCompiledFile() { await _app.StartWatcherAsync(); @@ -57,7 +57,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests Assert.Equal(1, types); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8267")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/8267")] public async Task DeleteSourceFolder() { await _app.StartWatcherAsync(); @@ -73,7 +73,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests Assert.Equal(1, types); } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8987")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/8987")] public async Task RenameCompiledFile() { await _app.StartWatcherAsync(); @@ -86,7 +86,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/8267")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/8267")] public async Task ChangeExcludedFile() { await _app.StartWatcherAsync(); @@ -100,7 +100,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/8267")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/8267")] public async Task ListsFiles() { await _app.PrepareAsync(); diff --git a/src/Tools/dotnet-watch/test/NoDepsAppTests.cs b/src/Tools/dotnet-watch/test/NoDepsAppTests.cs index 4f2b420492..b9b2352efc 100644 --- a/src/Tools/dotnet-watch/test/NoDepsAppTests.cs +++ b/src/Tools/dotnet-watch/test/NoDepsAppTests.cs @@ -24,7 +24,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests _output = logger; } - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8267")] + [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/8267")] public async Task RestartProcessOnFileChange() { await _app.StartWatcherAsync(new[] { "--no-exit" }); @@ -43,7 +43,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests } [ConditionalFact] - [SkipOnHelix("https://github.com/aspnet/AspNetCore/issues/8267")] + [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/8267")] public async Task RestartProcessThatTerminatesAfterFileChange() { await _app.StartWatcherAsync(); diff --git a/src/Tools/dotnet-watch/test/ProgramTests.cs b/src/Tools/dotnet-watch/test/ProgramTests.cs index 0e7dff9b82..6e24eb13d2 100644 --- a/src/Tools/dotnet-watch/test/ProgramTests.cs +++ b/src/Tools/dotnet-watch/test/ProgramTests.cs @@ -28,7 +28,7 @@ namespace Microsoft.DotNet.Watcher.Tools.Tests { _tempDir .WithCSharpProject("testproj") - .WithTargetFrameworks("netcoreapp3.1") + .WithTargetFrameworks("netcoreapp5.0") .Dir() .WithFile("Program.cs") .Create(); diff --git a/src/Tools/dotnet-watch/test/TestProjects/AppWithDeps/AppWithDeps.csproj b/src/Tools/dotnet-watch/test/TestProjects/AppWithDeps/AppWithDeps.csproj index d0cde953c7..7399c1018d 100644 --- a/src/Tools/dotnet-watch/test/TestProjects/AppWithDeps/AppWithDeps.csproj +++ b/src/Tools/dotnet-watch/test/TestProjects/AppWithDeps/AppWithDeps.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>netcoreapp3.1</TargetFramework> + <TargetFramework>netcoreapp5.0</TargetFramework> <OutputType>exe</OutputType> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> diff --git a/src/Tools/dotnet-watch/test/TestProjects/GlobbingApp/GlobbingApp.csproj b/src/Tools/dotnet-watch/test/TestProjects/GlobbingApp/GlobbingApp.csproj index 9f015b1ee4..8f8043d0de 100644 --- a/src/Tools/dotnet-watch/test/TestProjects/GlobbingApp/GlobbingApp.csproj +++ b/src/Tools/dotnet-watch/test/TestProjects/GlobbingApp/GlobbingApp.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>netcoreapp3.1</TargetFramework> + <TargetFramework>netcoreapp5.0</TargetFramework> <OutputType>exe</OutputType> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> diff --git a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/KitchenSink.csproj b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/KitchenSink.csproj index af6de1b33f..6de103d382 100644 --- a/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/KitchenSink.csproj +++ b/src/Tools/dotnet-watch/test/TestProjects/KitchenSink/KitchenSink.csproj @@ -9,7 +9,7 @@ <PropertyGroup> <OutputType>Exe</OutputType> - <TargetFramework>netcoreapp3.1</TargetFramework> + <TargetFramework>netcoreapp5.0</TargetFramework> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> diff --git a/src/Tools/dotnet-watch/test/TestProjects/NoDepsApp/NoDepsApp.csproj b/src/Tools/dotnet-watch/test/TestProjects/NoDepsApp/NoDepsApp.csproj index 95412443e6..110ff7686b 100644 --- a/src/Tools/dotnet-watch/test/TestProjects/NoDepsApp/NoDepsApp.csproj +++ b/src/Tools/dotnet-watch/test/TestProjects/NoDepsApp/NoDepsApp.csproj @@ -1,7 +1,7 @@ <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> - <TargetFramework>netcoreapp3.1</TargetFramework> + <TargetFramework>netcoreapp5.0</TargetFramework> <OutputType>exe</OutputType> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> diff --git a/startvs.cmd b/startvs.cmd index 0de7bb7d56..c9613224fc 100644 --- a/startvs.cmd +++ b/startvs.cmd @@ -13,7 +13,7 @@ SET DOTNET_MULTILEVEL_LOOKUP=0 :: Put our local dotnet.exe on PATH first so Visual Studio knows which one to use SET PATH=%DOTNET_ROOT%;%PATH% -SET sln=%1 +SET sln=%~1 IF "%sln%"=="" ( echo Error^: Expected argument ^<SLN_FILE^> @@ -27,4 +27,4 @@ IF NOT EXIST "%DOTNET_ROOT%\dotnet.exe" ( exit /b 1 ) -start %sln% +start "" "%sln%"