Repository: aspnet/BasicMiddleware
Branch: master
Commit: 87d4df52fa20
Files: 283
Total size: 814.0 KB
Directory structure:
gitextract_jlb0z59u/
├── .appveyor.yml
├── .gitattributes
├── .gitignore
├── .travis.yml
├── .vsts-pipelines/
│ └── builds/
│ ├── ci-internal.yml
│ └── ci-public.yml
├── BasicMiddleware.sln
├── CONTRIBUTING.md
├── Directory.Build.props
├── Directory.Build.targets
├── LICENSE.txt
├── NuGet.config
├── NuGetPackageVerifier.json
├── README.md
├── benchmarks/
│ └── Microsoft.AspNetCore.ResponseCompression.Benchmarks/
│ ├── AssemblyInfo.cs
│ ├── Microsoft.AspNetCore.ResponseCompression.Benchmarks.csproj
│ └── ResponseCompressionProviderBenchmark.cs
├── build/
│ ├── Key.snk
│ ├── dependencies.props
│ ├── repo.props
│ └── sources.props
├── build.cmd
├── build.sh
├── korebuild-lock.txt
├── korebuild.json
├── run.cmd
├── run.ps1
├── run.sh
├── samples/
│ ├── HostFilteringSample/
│ │ ├── HostFilteringSample.csproj
│ │ ├── Program.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── Startup.cs
│ │ ├── appsettings.Development.json
│ │ ├── appsettings.Production.json
│ │ └── appsettings.json
│ ├── HttpOverridesSample/
│ │ ├── HttpOverridesSample.csproj
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ └── Startup.cs
│ ├── HttpsPolicySample/
│ │ ├── HttpsPolicySample.csproj
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── Startup.cs
│ │ └── testCert.pfx
│ ├── ResponseBufferingSample/
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── ResponseBufferingSample.csproj
│ │ └── Startup.cs
│ ├── ResponseCompressionSample/
│ │ ├── CustomCompressionProvider.cs
│ │ ├── LoremIpsum.cs
│ │ ├── Properties/
│ │ │ └── launchSettings.json
│ │ ├── ResponseCompressionSample.csproj
│ │ ├── Startup.cs
│ │ └── testfile1kb.txt
│ └── RewriteSample/
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Rewrite.txt
│ ├── RewriteSample.csproj
│ ├── Startup.cs
│ ├── UrlRewrite.xml
│ └── testCert.pfx
├── src/
│ ├── Directory.Build.props
│ ├── Microsoft.AspNetCore.Buffering/
│ │ ├── BufferingWriteStream.cs
│ │ ├── HttpBufferingFeature.cs
│ │ ├── Microsoft.AspNetCore.Buffering.csproj
│ │ ├── ResponseBufferingMiddleware.cs
│ │ ├── ResponseBufferingMiddlewareExtensions.cs
│ │ └── SendFileFeatureWrapper.cs
│ ├── Microsoft.AspNetCore.HostFiltering/
│ │ ├── HostFilteringBuilderExtensions.cs
│ │ ├── HostFilteringMiddleware.cs
│ │ ├── HostFilteringOptions.cs
│ │ ├── HostFilteringServicesExtensions.cs
│ │ ├── Microsoft.AspNetCore.HostFiltering.csproj
│ │ └── baseline.netcore.json
│ ├── Microsoft.AspNetCore.HttpOverrides/
│ │ ├── ForwardedHeaders.cs
│ │ ├── ForwardedHeadersDefaults.cs
│ │ ├── ForwardedHeadersExtensions.cs
│ │ ├── ForwardedHeadersMiddleware.cs
│ │ ├── ForwardedHeadersOptions.cs
│ │ ├── HttpMethodOverrideExtensions.cs
│ │ ├── HttpMethodOverrideMiddleware.cs
│ │ ├── HttpMethodOverrideOptions.cs
│ │ ├── IPNetwork.cs
│ │ ├── Internal/
│ │ │ └── IPEndPointParser.cs
│ │ ├── Microsoft.AspNetCore.HttpOverrides.csproj
│ │ ├── baseline.net45.json
│ │ └── baseline.netcore.json
│ ├── Microsoft.AspNetCore.HttpsPolicy/
│ │ ├── HstsBuilderExtensions.cs
│ │ ├── HstsMiddleware.cs
│ │ ├── HstsOptions.cs
│ │ ├── HstsServicesExtensions.cs
│ │ ├── HttpsRedirectionBuilderExtensions.cs
│ │ ├── HttpsRedirectionMiddleware.cs
│ │ ├── HttpsRedirectionOptions.cs
│ │ ├── HttpsRedirectionServicesExtensions.cs
│ │ ├── Microsoft.AspNetCore.HttpsPolicy.csproj
│ │ ├── baseline.netcore.json
│ │ └── internal/
│ │ ├── HstsLoggingExtensions.cs
│ │ └── HttpsLoggingExtensions.cs
│ ├── Microsoft.AspNetCore.ResponseCompression/
│ │ ├── BodyWrapperStream.cs
│ │ ├── BrotliCompressionProvider.cs
│ │ ├── BrotliCompressionProviderOptions.cs
│ │ ├── CompressionProviderCollection.cs
│ │ ├── CompressionProviderFactory.cs
│ │ ├── GzipCompressionProvider.cs
│ │ ├── GzipCompressionProviderOptions.cs
│ │ ├── ICompressionProvider.cs
│ │ ├── IResponseCompressionProvider.cs
│ │ ├── Microsoft.AspNetCore.ResponseCompression.csproj
│ │ ├── Properties/
│ │ │ └── AssemblyInfo.cs
│ │ ├── ResponseCompressionBuilderExtensions.cs
│ │ ├── ResponseCompressionDefaults.cs
│ │ ├── ResponseCompressionMiddleware.cs
│ │ ├── ResponseCompressionOptions.cs
│ │ ├── ResponseCompressionProvider.cs
│ │ ├── ResponseCompressionServicesExtensions.cs
│ │ ├── baseline.netcore.json
│ │ ├── baseline.netframework.json
│ │ └── internal/
│ │ └── ResponseCompressionLoggingExtensions.cs
│ └── Microsoft.AspNetCore.Rewrite/
│ ├── ApacheModRewriteOptionsExtensions.cs
│ ├── Extensions/
│ │ └── RewriteMiddlewareLoggingExtensions.cs
│ ├── IISUrlRewriteOptionsExtensions.cs
│ ├── IRule.cs
│ ├── Internal/
│ │ ├── ApacheModRewrite/
│ │ │ ├── ApacheModRewriteRule.cs
│ │ │ ├── Condition.cs
│ │ │ ├── ConditionEvaluator.cs
│ │ │ ├── ConditionPatternParser.cs
│ │ │ ├── ConditionType.cs
│ │ │ ├── CookieActionFactory.cs
│ │ │ ├── FileParser.cs
│ │ │ ├── FlagParser.cs
│ │ │ ├── FlagType.cs
│ │ │ ├── Flags.cs
│ │ │ ├── OperationType.cs
│ │ │ ├── ParsedModRewriteCondition.cs
│ │ │ ├── RuleBuilder.cs
│ │ │ ├── RuleRegexParser.cs
│ │ │ ├── SegmentType.cs
│ │ │ ├── ServerVariables.cs
│ │ │ ├── TestStringParser.cs
│ │ │ └── Tokenizer.cs
│ │ ├── BackReferenceCollection.cs
│ │ ├── DelegateRule.cs
│ │ ├── IISUrlRewrite/
│ │ │ ├── ActionType.cs
│ │ │ ├── Condition.cs
│ │ │ ├── ConditionCollection.cs
│ │ │ ├── ConditionEvaluator.cs
│ │ │ ├── IISRewriteMap.cs
│ │ │ ├── IISRewriteMapCollection.cs
│ │ │ ├── IISUrlRewriteRule.cs
│ │ │ ├── InputParser.cs
│ │ │ ├── InvalidUrlRewriteFormatException.cs
│ │ │ ├── LogicalGrouping.cs
│ │ │ ├── MatchType.cs
│ │ │ ├── PatternSyntax.cs
│ │ │ ├── RedirectType.cs
│ │ │ ├── RewriteMapParser.cs
│ │ │ ├── RewriteTags.cs
│ │ │ ├── ServerVariables.cs
│ │ │ ├── UriMatchCondition.cs
│ │ │ ├── UriMatchPart.cs
│ │ │ ├── UrlRewriteFileParser.cs
│ │ │ └── UrlRewriteRuleBuilder.cs
│ │ ├── MatchResults.cs
│ │ ├── ParserContext.cs
│ │ ├── Pattern.cs
│ │ ├── PatternSegment.cs
│ │ ├── PatternSegments/
│ │ │ ├── ConditionMatchSegment.cs
│ │ │ ├── DateTimeSegment.cs
│ │ │ ├── HeaderSegment.cs
│ │ │ ├── IsHttpsModSegment.cs
│ │ │ ├── IsHttpsUrlSegment.cs
│ │ │ ├── IsIPV6Segment.cs
│ │ │ ├── LiteralSegment.cs
│ │ │ ├── LocalAddressSegment.cs
│ │ │ ├── LocalPortSegment.cs
│ │ │ ├── QueryStringSegment.cs
│ │ │ ├── RemoteAddressSegment.cs
│ │ │ ├── RemotePortSegment.cs
│ │ │ ├── RequestFilenameSegment.cs
│ │ │ ├── RequestMethodSegment.cs
│ │ │ ├── RewriteMapSegment.cs
│ │ │ ├── RuleMatchSegment.cs
│ │ │ ├── SchemeSegment.cs
│ │ │ ├── ServerProtocolSegment.cs
│ │ │ ├── ToLowerSegment.cs
│ │ │ ├── UrlEncodeSegment.cs
│ │ │ └── UrlSegment.cs
│ │ ├── RedirectRule.cs
│ │ ├── RedirectToHttpsRule.cs
│ │ ├── RedirectToWwwRule.cs
│ │ ├── RewriteRule.cs
│ │ ├── UrlAction.cs
│ │ ├── UrlActions/
│ │ │ ├── AbortAction.cs
│ │ │ ├── ChangeCookieAction.cs
│ │ │ ├── CustomResponseAction.cs
│ │ │ ├── ForbiddenAction.cs
│ │ │ ├── GoneAction.cs
│ │ │ ├── NoneAction.cs
│ │ │ ├── RedirectAction.cs
│ │ │ └── RewriteAction.cs
│ │ ├── UrlMatch.cs
│ │ └── UrlMatches/
│ │ ├── ExactMatch.cs
│ │ ├── FileSizeMatch.cs
│ │ ├── IntegerMatch.cs
│ │ ├── IntegerOperation.cs
│ │ ├── IsDirectoryMatch.cs
│ │ ├── IsFileMatch.cs
│ │ ├── RegexMatch.cs
│ │ ├── StringMatch.cs
│ │ └── StringOperation.cs
│ ├── Microsoft.AspNetCore.Rewrite.csproj
│ ├── Properties/
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ ├── RewriteBuilderExtensions.cs
│ ├── RewriteContext.cs
│ ├── RewriteMiddleware.cs
│ ├── RewriteOptions.cs
│ ├── RewriteOptionsExtensions.cs
│ ├── RuleResult.cs
│ └── baseline.netcore.json
├── test/
│ ├── Directory.Build.props
│ ├── Microsoft.AspNetCore.Buffering.Tests/
│ │ ├── Microsoft.AspNetCore.Buffering.Tests.csproj
│ │ └── ResponseBufferingMiddlewareTests.cs
│ ├── Microsoft.AspNetCore.HostFiltering.Tests/
│ │ ├── HostFilteringMiddlewareTests.cs
│ │ └── Microsoft.AspNetCore.HostFiltering.Tests.csproj
│ ├── Microsoft.AspNetCore.HttpOverrides.Tests/
│ │ ├── ForwardedHeadersMiddlewareTest.cs
│ │ ├── HttpMethodOverrideMiddlewareTest.cs
│ │ ├── IPEndPointParserTest.cs
│ │ ├── IPNetworkTest.cs
│ │ └── Microsoft.AspNetCore.HttpOverrides.Tests.csproj
│ ├── Microsoft.AspNetCore.HttpsPolicy.Tests/
│ │ ├── HstsMiddlewareTests.cs
│ │ ├── HttpsPolicyTests.cs
│ │ ├── HttpsRedirectionMiddlewareTests.cs
│ │ └── Microsoft.AspNetCore.HttpsPolicy.Tests.csproj
│ ├── Microsoft.AspNetCore.ResponseCompression.Tests/
│ │ ├── BodyWrapperStreamTests.cs
│ │ ├── Microsoft.AspNetCore.ResponseCompression.Tests.csproj
│ │ ├── ResponseCompressionMiddlewareTest.cs
│ │ └── testfile1kb.txt
│ └── Microsoft.AspNetCore.Rewrite.Tests/
│ ├── ApacheModRewrite/
│ │ ├── ConditionPatternParserTest.cs
│ │ ├── CookieActionFactoryTest.cs
│ │ ├── FlagParserTest.cs
│ │ ├── FormatExceptionTests.cs
│ │ ├── ModRewriteMiddlewareTest.cs
│ │ ├── RewriteTokenizerTest.cs
│ │ ├── RuleBuilderTest.cs
│ │ ├── RuleRegexParserTest.cs
│ │ └── TestStringParserTests.cs
│ ├── IISUrlRewrite/
│ │ ├── FileParserTests.cs
│ │ ├── FormatExceptionHandlingTests.cs
│ │ ├── InputParserTests.cs
│ │ ├── InvalidUrlRewriteFormatExceptionHandlingTests.cs
│ │ ├── MiddleWareTests.cs
│ │ ├── RewriteMapParserTests.cs
│ │ ├── ServerVariableTests.cs
│ │ └── UrlRewriteApplicationTests.cs
│ ├── Microsoft.AspNetCore.Rewrite.Tests.csproj
│ ├── MiddlewareTests.cs
│ ├── PatternSegments/
│ │ ├── ConditionMatchSegmentTests.cs
│ │ ├── DateTimeSegmentTests.cs
│ │ ├── HeaderSegmentTests.cs
│ │ ├── IsHttpsModSegmentTests.cs
│ │ ├── IsHttpsSegmentTests.cs
│ │ ├── IsIPV6SegmentTests.cs
│ │ ├── LIteralSegmentTests.cs
│ │ ├── LocalAddressSegmentTests.cs
│ │ ├── LocalPortSegmentTests.cs
│ │ ├── QueryStringSegmentTests.cs
│ │ ├── RemoteAddressSegmentTests.cs
│ │ ├── RemotePortSegmentTests.cs
│ │ ├── RequestFilenameSegmentTests.cs
│ │ ├── RequestMethodSegmentTests.cs
│ │ ├── RuleMatchSegmentTests.cs
│ │ ├── SchemeSegmentTests.cs
│ │ ├── ServerProtocolSegmentTests.cs
│ │ ├── ToLowerSegmentTests.cs
│ │ ├── UrlEncodeSegmentTests.cs
│ │ └── UrlSegmentTests.cs
│ ├── UrlActions/
│ │ ├── AbortActionTests.cs
│ │ ├── ChangeCookieActionTests.cs
│ │ ├── ForbiddenActionTests.cs
│ │ └── GoneActionTests.cs
│ └── UrlMatches/
│ ├── ExactMatchTests.cs
│ ├── IntegerMatchTests.cs
│ └── StringMatchTests.cs
└── version.props
================================================
FILE CONTENTS
================================================
================================================
FILE: .appveyor.yml
================================================
init:
- git config --global core.autocrlf true
branches:
only:
- master
- /^release\/.*$/
- /^(.*\/)?ci-.*$/
build_script:
- ps: .\run.ps1 default-build
clone_depth: 1
environment:
global:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: 1
test: 'off'
deploy: 'off'
os: Visual Studio 2017
================================================
FILE: .gitattributes
================================================
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.jpg binary
*.png binary
*.gif binary
*.cs text=auto diff=csharp
*.vb text=auto
*.resx text=auto
*.c text=auto
*.cpp text=auto
*.cxx text=auto
*.h text=auto
*.hxx text=auto
*.py text=auto
*.rb text=auto
*.java text=auto
*.html text=auto
*.htm text=auto
*.css text=auto
*.scss text=auto
*.sass text=auto
*.less text=auto
*.js text=auto
*.lisp text=auto
*.clj text=auto
*.sql text=auto
*.php text=auto
*.lua text=auto
*.m text=auto
*.asm text=auto
*.erl text=auto
*.fs text=auto
*.fsx text=auto
*.hs text=auto
*.csproj text=auto
*.vbproj text=auto
*.fsproj text=auto
*.dbproj text=auto
*.sln text=auto eol=crlf
*.sh eol=lf
================================================
FILE: .gitignore
================================================
[Oo]bj/
[Bb]in/
TestResults/
.nuget/
*.sln.ide/
_ReSharper.*/
packages/
artifacts/
PublishProfiles/
*.user
*.suo
*.cache
*.docstates
_ReSharper.*
nuget.exe
project.lock.json
*net45.csproj
*net451.csproj
*k10.csproj
*.psess
*.vsp
*.pidb
*.userprefs
*DS_Store
*.ncrunchsolution
*.*sdf
*.ipch
.vs/
.build/
.testPublish/
.idea/
.vscode/
*.nuget.props
*.nuget.targets
global.json
================================================
FILE: .travis.yml
================================================
language: csharp
sudo: false
dist: trusty
env:
global:
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
mono: none
os:
- linux
- osx
osx_image: xcode8.2
addons:
apt:
packages:
- libunwind8
branches:
only:
- master
- /^release\/.*$/
- /^(.*\/)?ci-.*$/
before_install:
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
/usr/local/lib/; fi
script:
- ./build.sh
================================================
FILE: .vsts-pipelines/builds/ci-internal.yml
================================================
trigger:
- master
- release/*
resources:
repositories:
- repository: buildtools
type: git
name: aspnet-BuildTools
ref: refs/heads/master
phases:
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
================================================
FILE: .vsts-pipelines/builds/ci-public.yml
================================================
trigger:
- master
- release/*
# See https://github.com/aspnet/BuildTools
resources:
repositories:
- repository: buildtools
type: github
endpoint: DotNet-Bot GitHub Connection
name: aspnet/BuildTools
ref: refs/heads/master
phases:
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
================================================
FILE: BasicMiddleware.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 15.0.26730.03
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpOverrides", "src\Microsoft.AspNetCore.HttpOverrides\Microsoft.AspNetCore.HttpOverrides.csproj", "{517308C3-B477-4B01-B461-CAB9C10B6928}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A5076D28-FA7E-4606-9410-FEDD0D603527}"
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8437B0F3-3894-4828-A945-A9187F37631D}"
ProjectSection(SolutionItems) = preProject
test\Directory.Build.props = test\Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpOverrides.Tests", "test\Microsoft.AspNetCore.HttpOverrides.Tests\Microsoft.AspNetCore.HttpOverrides.Tests.csproj", "{D6341B92-3416-4F11-8DF4-CB274296175F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Buffering", "src\Microsoft.AspNetCore.Buffering\Microsoft.AspNetCore.Buffering.csproj", "{2363D0DD-A3BF-437E-9B64-B33AE132D875}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Buffering.Tests", "test\Microsoft.AspNetCore.Buffering.Tests\Microsoft.AspNetCore.Buffering.Tests.csproj", "{F5F1D123-9C81-4A9E-8644-AA46B8E578FB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9587FE9F-5A17-42C4-8021-E87F59CECB98}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ResponseBufferingSample", "samples\ResponseBufferingSample\ResponseBufferingSample.csproj", "{E5C55B80-7827-40EB-B661-32B0E0E431CA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpOverridesSample", "samples\HttpOverridesSample\HttpOverridesSample.csproj", "{7F95478D-E1D4-4A64-BA42-B041591A96EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Rewrite", "src\Microsoft.AspNetCore.Rewrite\Microsoft.AspNetCore.Rewrite.csproj", "{0E7CA1A7-1DC3-4CE6-B9C7-1688FE1410F1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RewriteSample", "samples\RewriteSample\RewriteSample.csproj", "{9E049645-13BC-4598-89E1-5B43D36E5D14}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Rewrite.Tests", "test\Microsoft.AspNetCore.Rewrite.Tests\Microsoft.AspNetCore.Rewrite.Tests.csproj", "{31794F9E-A1AA-4535-B03C-A3233737CD1A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ResponseCompression", "src\Microsoft.AspNetCore.ResponseCompression\Microsoft.AspNetCore.ResponseCompression.csproj", "{45308A9D-F4C6-46A8-A24F-E73D995CC223}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ResponseCompression.Tests", "test\Microsoft.AspNetCore.ResponseCompression.Tests\Microsoft.AspNetCore.ResponseCompression.Tests.csproj", "{3360A5D1-70C0-49EE-9051-04A6A6B836DC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ResponseCompressionSample", "samples\ResponseCompressionSample\ResponseCompressionSample.csproj", "{B2A3CE38-51B2-4486-982C-98C380AF140E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{59A9B64C-E9BE-409E-89A2-58D72E2918F5}"
ProjectSection(SolutionItems) = preProject
.appveyor.yml = .appveyor.yml
.gitattributes = .gitattributes
.gitignore = .gitignore
.travis.yml = .travis.yml
build.cmd = build.cmd
build.ps1 = build.ps1
build.sh = build.sh
CONTRIBUTING.md = CONTRIBUTING.md
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
LICENSE.txt = LICENSE.txt
NuGet.config = NuGet.config
NuGetPackageVerifier.json = NuGetPackageVerifier.json
README.md = README.md
version.xml = version.xml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpsPolicy", "src\Microsoft.AspNetCore.HttpsPolicy\Microsoft.AspNetCore.HttpsPolicy.csproj", "{4D39C29B-4EC8-497C-B411-922DA494D71B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpsPolicySample", "samples\HttpsPolicySample\HttpsPolicySample.csproj", "{AC424AEE-4883-49C6-945F-2FC916B8CA1C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HttpsPolicy.Tests", "test\Microsoft.AspNetCore.HttpsPolicy.Tests\Microsoft.AspNetCore.HttpsPolicy.Tests.csproj", "{1C67B0F1-6E70-449E-A2F1-98B9D5C576CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostFilteringSample", "samples\HostFilteringSample\HostFilteringSample.csproj", "{368B00A2-992A-4B0E-9085-A8136A22922D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{5CEA6F31-A829-4A02-8CD5-EC3DDD4CC1EA}"
ProjectSection(SolutionItems) = preProject
build\dependencies.props = build\dependencies.props
build\repo.props = build\repo.props
build\sources.props = build\sources.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HostFiltering.Tests", "test\Microsoft.AspNetCore.HostFiltering.Tests\Microsoft.AspNetCore.HostFiltering.Tests.csproj", "{4BC947ED-13B8-4BE6-82A4-96A48D86980B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.HostFiltering", "src\Microsoft.AspNetCore.HostFiltering\Microsoft.AspNetCore.HostFiltering.csproj", "{762F7276-C916-4111-A6C0-41668ABB3823}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{C6DA6317-30FC-42FE-891C-64E75D88FF12}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.ResponseCompression.Benchmarks", "benchmarks\Microsoft.AspNetCore.ResponseCompression.Benchmarks\Microsoft.AspNetCore.ResponseCompression.Benchmarks.csproj", "{5AF10E85-5076-40B9-84CF-9830B585ABE5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{517308C3-B477-4B01-B461-CAB9C10B6928}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{517308C3-B477-4B01-B461-CAB9C10B6928}.Debug|Any CPU.Build.0 = Debug|Any CPU
{517308C3-B477-4B01-B461-CAB9C10B6928}.Release|Any CPU.ActiveCfg = Release|Any CPU
{517308C3-B477-4B01-B461-CAB9C10B6928}.Release|Any CPU.Build.0 = Release|Any CPU
{D6341B92-3416-4F11-8DF4-CB274296175F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6341B92-3416-4F11-8DF4-CB274296175F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6341B92-3416-4F11-8DF4-CB274296175F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6341B92-3416-4F11-8DF4-CB274296175F}.Release|Any CPU.Build.0 = Release|Any CPU
{2363D0DD-A3BF-437E-9B64-B33AE132D875}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2363D0DD-A3BF-437E-9B64-B33AE132D875}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2363D0DD-A3BF-437E-9B64-B33AE132D875}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2363D0DD-A3BF-437E-9B64-B33AE132D875}.Release|Any CPU.Build.0 = Release|Any CPU
{F5F1D123-9C81-4A9E-8644-AA46B8E578FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5F1D123-9C81-4A9E-8644-AA46B8E578FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5F1D123-9C81-4A9E-8644-AA46B8E578FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5F1D123-9C81-4A9E-8644-AA46B8E578FB}.Release|Any CPU.Build.0 = Release|Any CPU
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Release|Any CPU.Build.0 = Release|Any CPU
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Release|Any CPU.Build.0 = Release|Any CPU
{0E7CA1A7-1DC3-4CE6-B9C7-1688FE1410F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E7CA1A7-1DC3-4CE6-B9C7-1688FE1410F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E7CA1A7-1DC3-4CE6-B9C7-1688FE1410F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E7CA1A7-1DC3-4CE6-B9C7-1688FE1410F1}.Release|Any CPU.Build.0 = Release|Any CPU
{9E049645-13BC-4598-89E1-5B43D36E5D14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E049645-13BC-4598-89E1-5B43D36E5D14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E049645-13BC-4598-89E1-5B43D36E5D14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E049645-13BC-4598-89E1-5B43D36E5D14}.Release|Any CPU.Build.0 = Release|Any CPU
{31794F9E-A1AA-4535-B03C-A3233737CD1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31794F9E-A1AA-4535-B03C-A3233737CD1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31794F9E-A1AA-4535-B03C-A3233737CD1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31794F9E-A1AA-4535-B03C-A3233737CD1A}.Release|Any CPU.Build.0 = Release|Any CPU
{45308A9D-F4C6-46A8-A24F-E73D995CC223}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45308A9D-F4C6-46A8-A24F-E73D995CC223}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45308A9D-F4C6-46A8-A24F-E73D995CC223}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45308A9D-F4C6-46A8-A24F-E73D995CC223}.Release|Any CPU.Build.0 = Release|Any CPU
{3360A5D1-70C0-49EE-9051-04A6A6B836DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3360A5D1-70C0-49EE-9051-04A6A6B836DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3360A5D1-70C0-49EE-9051-04A6A6B836DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3360A5D1-70C0-49EE-9051-04A6A6B836DC}.Release|Any CPU.Build.0 = Release|Any CPU
{B2A3CE38-51B2-4486-982C-98C380AF140E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B2A3CE38-51B2-4486-982C-98C380AF140E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B2A3CE38-51B2-4486-982C-98C380AF140E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B2A3CE38-51B2-4486-982C-98C380AF140E}.Release|Any CPU.Build.0 = Release|Any CPU
{4D39C29B-4EC8-497C-B411-922DA494D71B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D39C29B-4EC8-497C-B411-922DA494D71B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D39C29B-4EC8-497C-B411-922DA494D71B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D39C29B-4EC8-497C-B411-922DA494D71B}.Release|Any CPU.Build.0 = Release|Any CPU
{AC424AEE-4883-49C6-945F-2FC916B8CA1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC424AEE-4883-49C6-945F-2FC916B8CA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC424AEE-4883-49C6-945F-2FC916B8CA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC424AEE-4883-49C6-945F-2FC916B8CA1C}.Release|Any CPU.Build.0 = Release|Any CPU
{1C67B0F1-6E70-449E-A2F1-98B9D5C576CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C67B0F1-6E70-449E-A2F1-98B9D5C576CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C67B0F1-6E70-449E-A2F1-98B9D5C576CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C67B0F1-6E70-449E-A2F1-98B9D5C576CE}.Release|Any CPU.Build.0 = Release|Any CPU
{368B00A2-992A-4B0E-9085-A8136A22922D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{368B00A2-992A-4B0E-9085-A8136A22922D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{368B00A2-992A-4B0E-9085-A8136A22922D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{368B00A2-992A-4B0E-9085-A8136A22922D}.Release|Any CPU.Build.0 = Release|Any CPU
{4BC947ED-13B8-4BE6-82A4-96A48D86980B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4BC947ED-13B8-4BE6-82A4-96A48D86980B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4BC947ED-13B8-4BE6-82A4-96A48D86980B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4BC947ED-13B8-4BE6-82A4-96A48D86980B}.Release|Any CPU.Build.0 = Release|Any CPU
{762F7276-C916-4111-A6C0-41668ABB3823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{762F7276-C916-4111-A6C0-41668ABB3823}.Debug|Any CPU.Build.0 = Debug|Any CPU
{762F7276-C916-4111-A6C0-41668ABB3823}.Release|Any CPU.ActiveCfg = Release|Any CPU
{762F7276-C916-4111-A6C0-41668ABB3823}.Release|Any CPU.Build.0 = Release|Any CPU
{5AF10E85-5076-40B9-84CF-9830B585ABE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AF10E85-5076-40B9-84CF-9830B585ABE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AF10E85-5076-40B9-84CF-9830B585ABE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AF10E85-5076-40B9-84CF-9830B585ABE5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{517308C3-B477-4B01-B461-CAB9C10B6928} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
{D6341B92-3416-4F11-8DF4-CB274296175F} = {8437B0F3-3894-4828-A945-A9187F37631D}
{2363D0DD-A3BF-437E-9B64-B33AE132D875} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
{F5F1D123-9C81-4A9E-8644-AA46B8E578FB} = {8437B0F3-3894-4828-A945-A9187F37631D}
{E5C55B80-7827-40EB-B661-32B0E0E431CA} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
{7F95478D-E1D4-4A64-BA42-B041591A96EB} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
{0E7CA1A7-1DC3-4CE6-B9C7-1688FE1410F1} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
{9E049645-13BC-4598-89E1-5B43D36E5D14} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
{31794F9E-A1AA-4535-B03C-A3233737CD1A} = {8437B0F3-3894-4828-A945-A9187F37631D}
{45308A9D-F4C6-46A8-A24F-E73D995CC223} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
{3360A5D1-70C0-49EE-9051-04A6A6B836DC} = {8437B0F3-3894-4828-A945-A9187F37631D}
{B2A3CE38-51B2-4486-982C-98C380AF140E} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
{4D39C29B-4EC8-497C-B411-922DA494D71B} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
{AC424AEE-4883-49C6-945F-2FC916B8CA1C} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
{1C67B0F1-6E70-449E-A2F1-98B9D5C576CE} = {8437B0F3-3894-4828-A945-A9187F37631D}
{368B00A2-992A-4B0E-9085-A8136A22922D} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
{5CEA6F31-A829-4A02-8CD5-EC3DDD4CC1EA} = {59A9B64C-E9BE-409E-89A2-58D72E2918F5}
{4BC947ED-13B8-4BE6-82A4-96A48D86980B} = {8437B0F3-3894-4828-A945-A9187F37631D}
{762F7276-C916-4111-A6C0-41668ABB3823} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
{5AF10E85-5076-40B9-84CF-9830B585ABE5} = {C6DA6317-30FC-42FE-891C-64E75D88FF12}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4518E9CE-3680-4E05-9259-B64EA7807158}
EndGlobalSection
EndGlobal
================================================
FILE: CONTRIBUTING.md
================================================
Contributing
======
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo.
================================================
FILE: Directory.Build.props
================================================
Microsoft ASP.NET Corehttps://github.com/aspnet/BasicMiddlewaregit$(MSBuildThisFileDirectory)$(MSBuildThisFileDirectory)build\Key.snktruetrue
================================================
FILE: Directory.Build.targets
================================================
$(MicrosoftNETCoreApp21PackageVersion)$(MicrosoftNETCoreApp22PackageVersion)$(NETStandardLibrary20PackageVersion)99.9
================================================
FILE: LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) .NET Foundation and Contributors
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: NuGet.config
================================================
================================================
FILE: NuGetPackageVerifier.json
================================================
{
"Default": {
"rules": [
"DefaultCompositeRule"
]
}
}
================================================
FILE: README.md
================================================
ASP.NET Core Basic Middleware Components [Archived]
===================================================
**This GitHub project has been archived.** Ongoing development on this project can be found in .
This repo hosts a collection of basic middleware components for ASP.NET Core. This includes Buffering, HTTP Overrides, Response Compression, and URL Rewriting.
The Rewrite middleware can import rules from IIS's UrlRewrite and Apache's mod_rewrite.
This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [AspNetCore](https://github.com/aspnet/AspNetCore) repo.
================================================
FILE: benchmarks/Microsoft.AspNetCore.ResponseCompression.Benchmarks/AssemblyInfo.cs
================================================
// 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.
[assembly: BenchmarkDotNet.Attributes.AspNetCoreBenchmark]
================================================
FILE: benchmarks/Microsoft.AspNetCore.ResponseCompression.Benchmarks/Microsoft.AspNetCore.ResponseCompression.Benchmarks.csproj
================================================
Exenetcoreapp2.1
================================================
FILE: benchmarks/Microsoft.AspNetCore.ResponseCompression.Benchmarks/ResponseCompressionProviderBenchmark.cs
================================================
// 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 BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.ResponseCompression.Benchmarks
{
public class ResponseCompressionProviderBenchmark
{
[GlobalSetup]
public void GlobalSetup()
{
var services = new ServiceCollection()
.AddOptions()
.AddResponseCompression()
.BuildServiceProvider();
var options = new ResponseCompressionOptions();
Provider = new ResponseCompressionProvider(services, Options.Create(options));
}
[ParamsSource(nameof(EncodingStrings))]
public string AcceptEncoding { get; set; }
public static IEnumerable EncodingStrings()
{
return new[]
{
"gzip;q=0.8, compress;q=0.6, br;q=0.4",
"gzip, compress, br",
"br, compress, gzip",
"gzip, compress",
"identity",
"*"
};
}
public ResponseCompressionProvider Provider { get; set; }
[Benchmark]
public ICompressionProvider GetCompressionProvider()
{
var context = new DefaultHttpContext();
context.Request.Headers[HeaderNames.AcceptEncoding] = AcceptEncoding;
return Provider.GetCompressionProvider(context);
}
}
}
================================================
FILE: build/dependencies.props
================================================
$(MSBuildAllProjects);$(MSBuildThisFileFullPath)0.10.133.0.0-alpha1-20181011.33.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106053.0.0-alpha1-106052.1.32.2.0-preview2-26905-023.0.0-alpha1-1060515.6.14.10.02.0.30.10.02.3.12.4.0
================================================
FILE: build/repo.props
================================================
Internal.AspNetCore.Universe.Lineuphttps://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json
================================================
FILE: build/sources.props
================================================
$(DotNetRestoreSources)
$(RestoreSources);
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
$(RestoreSources);
https://api.nuget.org/v3/index.json;
================================================
FILE: build.cmd
================================================
@ECHO OFF
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
================================================
FILE: build.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs)
chmod +x "$DIR/run.sh"; sync
"$DIR/run.sh" default-build "$@"
================================================
FILE: korebuild-lock.txt
================================================
version:3.0.0-alpha1-20181011.3
commithash:e7569d931e994629267ab2646e9926140962b4ac
================================================
FILE: korebuild.json
================================================
{
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
"channel": "master"
}
================================================
FILE: run.cmd
================================================
@ECHO OFF
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
================================================
FILE: run.ps1
================================================
#!/usr/bin/env powershell
#requires -version 4
<#
.SYNOPSIS
Executes KoreBuild commands.
.DESCRIPTION
Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`.
.PARAMETER Command
The KoreBuild command to run.
.PARAMETER Path
The folder to build. Defaults to the folder containing this script.
.PARAMETER Channel
The channel of KoreBuild to download. Overrides the value from the config file.
.PARAMETER DotNetHome
The directory where .NET Core tools will be stored.
.PARAMETER ToolsSource
The base url where build tools can be downloaded. Overrides the value from the config file.
.PARAMETER Update
Updates KoreBuild to the latest version even if a lock file is present.
.PARAMETER Reinstall
Re-installs KoreBuild
.PARAMETER ConfigFile
The path to the configuration file that stores values. Defaults to korebuild.json.
.PARAMETER ToolsSourceSuffix
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
.PARAMETER CI
Sets up CI specific settings and variables.
.PARAMETER Arguments
Arguments to be passed to the command
.NOTES
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
in the file are overridden by command line parameters.
.EXAMPLE
Example config file:
```json
{
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
"channel": "master",
"toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
}
```
#>
[CmdletBinding(PositionalBinding = $false)]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Command,
[string]$Path = $PSScriptRoot,
[Alias('c')]
[string]$Channel,
[Alias('d')]
[string]$DotNetHome,
[Alias('s')]
[string]$ToolsSource,
[Alias('u')]
[switch]$Update,
[switch]$Reinstall,
[string]$ToolsSourceSuffix,
[string]$ConfigFile = $null,
[switch]$CI,
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Arguments
)
Set-StrictMode -Version 2
$ErrorActionPreference = 'Stop'
#
# Functions
#
function Get-KoreBuild {
$lockFile = Join-Path $Path 'korebuild-lock.txt'
if (!(Test-Path $lockFile) -or $Update) {
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
}
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
if (!$version) {
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
}
$version = $version.TrimStart('version:').Trim()
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
if ($Reinstall -and (Test-Path $korebuildPath)) {
Remove-Item -Force -Recurse $korebuildPath
}
if (!(Test-Path $korebuildPath)) {
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
try {
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
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 $tmpfile -DestinationPath $korebuildPath
}
else {
# Fallback to old approach for old installations of PowerShell
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
}
}
catch {
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
throw
}
finally {
Remove-Item $tmpfile -ErrorAction Ignore
}
}
return $korebuildPath
}
function Join-Paths([string]$path, [string[]]$childPaths) {
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
return $path
}
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
if ($RemotePath -notlike 'http*') {
Copy-Item $RemotePath $LocalPath
return
}
$retries = 10
while ($retries -gt 0) {
$retries -= 1
try {
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
return
}
catch {
Write-Verbose "Request failed. $retries retries remaining"
}
}
Write-Error "Download failed: '$RemotePath'."
}
#
# Main
#
# Load configuration or set defaults
$Path = Resolve-Path $Path
if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
if (Test-Path $ConfigFile) {
try {
$config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
if ($config) {
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
}
}
catch {
Write-Host -ForegroundColor Red $Error[0]
Write-Error "$ConfigFile contains invalid JSON."
exit 1
}
}
if (!$DotNetHome) {
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
else { Join-Path $PSScriptRoot '.dotnet'}
}
if (!$Channel) { $Channel = 'master' }
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
# Execute
$korebuildPath = Get-KoreBuild
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
try {
Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI
Invoke-KoreBuildCommand $Command @Arguments
}
finally {
Remove-Module 'KoreBuild' -ErrorAction Ignore
}
================================================
FILE: run.sh
================================================
#!/usr/bin/env bash
set -euo pipefail
#
# variables
#
RESET="\033[0m"
RED="\033[0;31m"
YELLOW="\033[0;33m"
MAGENTA="\033[0;95m"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
verbose=false
update=false
reinstall=false
repo_path="$DIR"
channel=''
tools_source=''
tools_source_suffix=''
ci=false
#
# Functions
#
__usage() {
echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] ...]"
echo ""
echo "Arguments:"
echo " command The command to be run."
echo " ... Arguments passed to the command. Variable number of arguments allowed."
echo ""
echo "Options:"
echo " --verbose Show verbose output."
echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.."
echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json."
echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
echo " --path The directory to build. Defaults to the directory containing the script."
echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file."
echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings."
echo " -u|--update Update to the latest KoreBuild even if the lock file is present."
echo " --reinstall Reinstall KoreBuild."
echo " --ci Apply CI specific settings and environment variables."
echo ""
echo "Description:"
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
if [[ "${1:-}" != '--no-exit' ]]; then
exit 2
fi
}
get_korebuild() {
local version
local lock_file="$repo_path/korebuild-lock.txt"
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix"
fi
version="$(grep 'version:*' -m 1 "$lock_file")"
if [[ "$version" == '' ]]; then
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
return 1
fi
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
if [ "$reinstall" = true ] && [ -d "$korebuild_path" ]; then
rm -rf "$korebuild_path"
fi
{
if [ ! -d "$korebuild_path" ]; then
mkdir -p "$korebuild_path"
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
tmpfile="$(mktemp)"
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then
unzip -q -d "$korebuild_path" "$tmpfile"
fi
rm "$tmpfile" || true
fi
source "$korebuild_path/KoreBuild.sh"
} || {
if [ -d "$korebuild_path" ]; then
echo "Cleaning up after failed installation"
rm -rf "$korebuild_path" || true
fi
return 1
}
}
__error() {
echo -e "${RED}error: $*${RESET}" 1>&2
}
__warn() {
echo -e "${YELLOW}warning: $*${RESET}"
}
__machine_has() {
hash "$1" > /dev/null 2>&1
return $?
}
__get_remote_file() {
local remote_path=$1
local local_path=$2
local remote_path_suffix=$3
if [[ "$remote_path" != 'http'* ]]; then
cp "$remote_path" "$local_path"
return 0
fi
local failed=false
if __machine_has wget; then
wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
else
failed=true
fi
if [ "$failed" = true ] && __machine_has curl; then
failed=false
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
fi
if [ "$failed" = true ]; then
__error "Download failed: $remote_path" 1>&2
return 1
fi
}
#
# main
#
command="${1:-}"
shift
while [[ $# -gt 0 ]]; do
case $1 in
-\?|-h|--help)
__usage --no-exit
exit 0
;;
-c|--channel|-Channel)
shift
channel="${1:-}"
[ -z "$channel" ] && __usage
;;
--config-file|-ConfigFile)
shift
config_file="${1:-}"
[ -z "$config_file" ] && __usage
if [ ! -f "$config_file" ]; then
__error "Invalid value for --config-file. $config_file does not exist."
exit 1
fi
;;
-d|--dotnet-home|-DotNetHome)
shift
DOTNET_HOME="${1:-}"
[ -z "$DOTNET_HOME" ] && __usage
;;
--path|-Path)
shift
repo_path="${1:-}"
[ -z "$repo_path" ] && __usage
;;
-s|--tools-source|-ToolsSource)
shift
tools_source="${1:-}"
[ -z "$tools_source" ] && __usage
;;
--tools-source-suffix|-ToolsSourceSuffix)
shift
tools_source_suffix="${1:-}"
[ -z "$tools_source_suffix" ] && __usage
;;
-u|--update|-Update)
update=true
;;
--reinstall|-[Rr]einstall)
reinstall=true
;;
--ci|-[Cc][Ii])
ci=true
;;
--verbose|-Verbose)
verbose=true
;;
--)
shift
break
;;
*)
break
;;
esac
shift
done
if ! __machine_has unzip; then
__error 'Missing required command: unzip'
exit 1
fi
if ! __machine_has curl && ! __machine_has wget; then
__error 'Missing required command. Either wget or curl is required.'
exit 1
fi
[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json"
if [ -f "$config_file" ]; then
if __machine_has jq ; then
if jq '.' "$config_file" >/dev/null ; then
config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")"
config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")"
else
__error "$config_file contains invalid JSON."
exit 1
fi
elif __machine_has python ; then
if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
else
__error "$config_file contains invalid JSON."
exit 1
fi
elif __machine_has python3 ; then
if python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
else
__error "$config_file contains invalid JSON."
exit 1
fi
else
__error 'Missing required command: jq or python. Could not parse the JSON file.'
exit 1
fi
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
fi
[ -z "$channel" ] && channel='master'
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
get_korebuild
set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" "$ci"
invoke_korebuild_command "$command" "$@"
================================================
FILE: samples/HostFilteringSample/HostFilteringSample.csproj
================================================
netcoreapp2.2;net461PreserveNewestPreserveNewestPreserveNewest
================================================
FILE: samples/HostFilteringSample/Program.cs
================================================
// 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.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace HostFilteringSample
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
var hostBuilder = new WebHostBuilder()
.ConfigureLogging((_, factory) =>
{
factory.SetMinimumLevel(LogLevel.Debug);
factory.AddConsole();
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.UseKestrel()
.UseStartup();
return hostBuilder.Build();
}
}
}
================================================
FILE: samples/HostFilteringSample/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:14124/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"HostFilteringSample": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:14125/"
}
}
}
================================================
FILE: samples/HostFilteringSample/Startup.cs
================================================
// 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.Builder;
using Microsoft.AspNetCore.HostFiltering;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace HostFilteringSample
{
public class Startup
{
public IConfiguration Config { get; }
public Startup(IConfiguration config)
{
Config = config;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddHostFiltering(options =>
{
});
// Fallback
services.PostConfigure(options =>
{
if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
{
// "AllowedHosts": "localhost;127.0.0.1;[::1]"
var hosts = Config["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
// Fall back to "*" to disable.
options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
}
});
// Change notification
services.AddSingleton>(new ConfigurationChangeTokenSource(Config));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHostFiltering();
app.Run(context =>
{
return context.Response.WriteAsync("Hello World! " + context.Request.Host);
});
}
}
}
================================================
FILE: samples/HostFilteringSample/appsettings.Development.json
================================================
{
"AllowedHosts": "localhost;127.0.0.1;[::1]"
}
================================================
FILE: samples/HostFilteringSample/appsettings.Production.json
================================================
{
"AllowedHosts": "example.com;localhost"
}
================================================
FILE: samples/HostFilteringSample/appsettings.json
================================================
{
}
================================================
FILE: samples/HttpOverridesSample/HttpOverridesSample.csproj
================================================
netcoreapp2.2;net461
================================================
FILE: samples/HttpOverridesSample/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1658/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"web": {
"commandName": "web",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
================================================
FILE: samples/HttpOverridesSample/Startup.cs
================================================
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
namespace HttpOverridesSample
{
public class Startup
{
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseHttpMethodOverride();
app.Run(async (context) =>
{
foreach (var header in context.Request.Headers)
{
await context.Response.WriteAsync($"{header.Key}: {header.Value}\r\n");
}
await context.Response.WriteAsync($"Method: {context.Request.Method}\r\n");
await context.Response.WriteAsync($"Scheme: {context.Request.Scheme}\r\n");
await context.Response.WriteAsync($"RemoteIP: {context.Connection.RemoteIpAddress}\r\n");
await context.Response.WriteAsync($"RemotePort: {context.Connection.RemotePort}\r\n");
});
}
// Entry point for the application.
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
// .UseIIS() // This repo can no longer reference IIS because IISIntegration depends on it.
.UseStartup()
.Build();
host.Run();
}
}
}
================================================
FILE: samples/HttpsPolicySample/HttpsPolicySample.csproj
================================================
net461;netcoreapp2.2netcoreapp2.2
================================================
FILE: samples/HttpsPolicySample/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:31894/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"HttpsSample": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000/"
}
}
}
================================================
FILE: samples/HttpsPolicySample/Startup.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace HttpsSample
{
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)
{
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status301MovedPermanently;
options.HttpsPort = 5001;
});
services.AddHsts(options =>
{
options.MaxAge = TimeSpan.FromDays(30);
options.Preload = true;
options.IncludeSubDomains = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment environment)
{
if (!environment.IsDevelopment())
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
}
// Entry point for the application.
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel(
options =>
{
options.Listen(new IPEndPoint(IPAddress.Loopback, 5001), listenOptions =>
{
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
options.Listen(new IPEndPoint(IPAddress.Loopback, 5000), listenOptions =>
{
});
})
.UseContentRoot(Directory.GetCurrentDirectory()) // for the cert file
.ConfigureLogging(factory =>
{
factory.SetMinimumLevel(LogLevel.Debug);
factory.AddConsole();
})
.UseStartup()
.Build();
host.Run();
}
}
}
================================================
FILE: samples/ResponseBufferingSample/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49657/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNET_ENV": "Development"
}
},
"web": {
"commandName": "web",
"environmentVariables": {
"Hosting:Environment": "Development"
}
}
}
}
================================================
FILE: samples/ResponseBufferingSample/ResponseBufferingSample.csproj
================================================
netcoreapp2.2;net461
================================================
FILE: samples/ResponseBufferingSample/Startup.cs
================================================
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace ResponseBufferingSample
{
public class Startup
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app)
{
app.UseResponseBuffering();
app.Run(async (context) =>
{
// Write some stuff
context.Response.ContentType = "text/other";
await context.Response.WriteAsync("Hello World!");
// ... more work ...
// Something went wrong and we want to replace the response
context.Response.StatusCode = 200;
context.Response.Headers.Clear();
context.Response.Body.SetLength(0);
// Try again
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hi Bob!");
});
}
// Entry point for the application.
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
// .UseIIS() // This repo can no longer reference IIS because IISIntegration depends on it.
.UseStartup()
.Build();
host.Run();
}
}
}
================================================
FILE: samples/ResponseCompressionSample/CustomCompressionProvider.cs
================================================
using System.IO;
using Microsoft.AspNetCore.ResponseCompression;
namespace ResponseCompressionSample
{
public class CustomCompressionProvider : ICompressionProvider
{
public string EncodingName => "custom";
public bool SupportsFlush => true;
public Stream CreateStream(Stream outputStream)
{
// Create a custom compression stream wrapper here
return outputStream;
}
}
}
================================================
FILE: samples/ResponseCompressionSample/LoremIpsum.cs
================================================
// 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 ResponseCompressionSample
{
internal static class LoremIpsum
{
internal const string Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit." +
"Ut velit mauris, egestas sed, gravida nec, ornare ut, mi. Aenean ut orci vel massa suscipit pulvinar.Nulla sollicitudin.Fusce varius, ligula non tempus aliquam, nunc turpis ullamcorper nibh, in tempus sapien eros vitae ligula.Pellentesque rhoncus nunc et augue.Integer id felis.Curabitur aliquet pellentesque diam. Integer quis metus vitae elit lobortis egestas.Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Morbi vel erat non mauris convallis vehicula.Nulla et sapien.Integer tortor tellus, aliquam faucibus, convallis id, congue eu, quam.Mauris ullamcorper felis vitae erat.Proin feugiat, augue non elementum posuere, metus purus iaculis lectus, et tristique ligula justo vitae magna." +
"Aliquam convallis sollicitudin purus. Praesent aliquam, enim at fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu lectus. Fusce vulputate sem at sapien.Vivamus leo. Aliquam euismod libero eu enim.Nulla nec felis sed leo placerat imperdiet.Aenean suscipit nulla in justo.Suspendisse cursus rutrum augue. Nulla tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus, felis magna fermentum augue, et ultricies lacus lorem varius purus. Curabitur eu amet.";
}
}
================================================
FILE: samples/ResponseCompressionSample/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:6164/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ResponseCompressionSample": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000/",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
================================================
FILE: samples/ResponseCompressionSample/ResponseCompressionSample.csproj
================================================
netcoreapp2.2;net461
================================================
FILE: samples/ResponseCompressionSample/Startup.cs
================================================
// 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.Compression;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace ResponseCompressionSample
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Configure(options => options.Level = CompressionLevel.Fastest);
services.AddResponseCompression(options =>
{
options.Providers.Add();
options.Providers.Add();
// .Append(TItem) is only available on Core.
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "image/svg+xml" });
////Example of using excluded and wildcard MIME types:
////Compress all MIME types except various media types, but do compress SVG images.
//options.MimeTypes = new[] { "*/*", "image/svg+xml" };
//options.ExcludedMimeTypes = new[] { "image/*", "audio/*", "video/*" };
});
}
public void Configure(IApplicationBuilder app)
{
app.UseResponseCompression();
app.Map("/testfile1kb.txt", fileApp =>
{
fileApp.Run(context =>
{
context.Response.ContentType = "text/plain";
return context.Response.SendFileAsync("testfile1kb.txt");
});
});
app.Map("/trickle", trickleApp =>
{
trickleApp.Run(async context =>
{
context.Response.ContentType = "text/plain";
// Disables compression on net451 because that GZipStream does not implement Flush.
context.Features.Get()?.DisableResponseBuffering();
for (int i = 0; i < 100; i++)
{
await context.Response.WriteAsync("a");
await context.Response.Body.FlushAsync();
await Task.Delay(TimeSpan.FromSeconds(1));
}
});
});
app.Run(async context =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync(LoremIpsum.Text);
});
}
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.ConfigureLogging(factory =>
{
factory.AddConsole()
.SetMinimumLevel(LogLevel.Debug);
})
.UseStartup()
.Build();
host.Run();
}
}
}
================================================
FILE: samples/ResponseCompressionSample/testfile1kb.txt
================================================
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
================================================
FILE: samples/RewriteSample/Properties/launchSettings.json
================================================
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:6156/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"RewriteSample": {
"commandName": "Project"
}
}
}
================================================
FILE: samples/RewriteSample/Rewrite.txt
================================================
# Rewrite path with additional sub directory
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC,OR]
RewriteCond %{SERVER_PORT} !^5000$
RewriteRule ^/(.*) http://www.example.com/$1 [L,R=302]
================================================
FILE: samples/RewriteSample/RewriteSample.csproj
================================================
netcoreapp2.2;net461
================================================
FILE: samples/RewriteSample/Startup.cs
================================================
// 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.IO;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.DependencyInjection;
namespace RewriteSample
{
public class Startup
{
public Startup(IHostingEnvironment environment)
{
Environment = environment;
}
public IHostingEnvironment Environment { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure(options =>
{
options.AddRedirect("(.*)/$", "$1")
.AddRewrite(@"app/(\d+)", "app?id=$1", skipRemainingRules: false)
.AddRedirectToHttps(302, 5001)
.AddIISUrlRewrite(Environment.ContentRootFileProvider, "UrlRewrite.xml")
.AddApacheModRewrite(Environment.ContentRootFileProvider, "Rewrite.txt");
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseRewriter();
app.Run(context =>
{
return context.Response.WriteAsync($"Rewritten Url: {context.Request.Path + context.Request.QueryString}");
});
}
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 5000);
options.Listen(IPAddress.Loopback, 5001, listenOptions =>
{
// Configure SSL
listenOptions.UseHttps("testCert.pfx", "testPassword");
});
})
.UseStartup()
.UseContentRoot(Directory.GetCurrentDirectory())
.Build();
host.Run();
}
}
}
================================================
FILE: samples/RewriteSample/UrlRewrite.xml
================================================
================================================
FILE: src/Directory.Build.props
================================================
================================================
FILE: src/Microsoft.AspNetCore.Buffering/BufferingWriteStream.cs
================================================
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Buffering
{
internal class BufferingWriteStream : Stream
{
private readonly Stream _innerStream;
private readonly MemoryStream _buffer = new MemoryStream();
private bool _isBuffering = true;
public BufferingWriteStream(Stream innerStream)
{
_innerStream = innerStream;
}
public override bool CanRead
{
get { return false; }
}
public override bool CanSeek
{
get { return _isBuffering; }
}
public override bool CanWrite
{
get { return _innerStream.CanWrite; }
}
public override long Length
{
get
{
if (_isBuffering)
{
return _buffer.Length;
}
// May throw
return _innerStream.Length;
}
}
// Clear/Reset the buffer by setting Position, Seek, or SetLength to 0. Random access is not supported.
public override long Position
{
get
{
if (_isBuffering)
{
return _buffer.Position;
}
// May throw
return _innerStream.Position;
}
set
{
if (_isBuffering)
{
if (value != 0)
{
throw new ArgumentOutOfRangeException(nameof(value), value, nameof(Position) + " can only be set to 0.");
}
_buffer.Position = value;
_buffer.SetLength(value);
}
else
{
// May throw
_innerStream.Position = value;
}
}
}
// Clear/Reset the buffer by setting Position, Seek, or SetLength to 0. Random access is not supported.
public override void SetLength(long value)
{
if (_isBuffering)
{
if (value != 0)
{
throw new ArgumentOutOfRangeException(nameof(value), value, nameof(Length) + " can only be set to 0.");
}
_buffer.Position = value;
_buffer.SetLength(value);
}
else
{
// May throw
_innerStream.SetLength(value);
}
}
// Clear/Reset the buffer by setting Position, Seek, or SetLength to 0. Random access is not supported.
public override long Seek(long offset, SeekOrigin origin)
{
if (_isBuffering)
{
if (origin != SeekOrigin.Begin)
{
throw new ArgumentException(nameof(origin), nameof(Seek) + " can only be set to " + nameof(SeekOrigin.Begin) + ".");
}
if (offset != 0)
{
throw new ArgumentOutOfRangeException(nameof(offset), offset, nameof(Seek) + " can only be set to 0.");
}
_buffer.SetLength(offset);
return _buffer.Seek(offset, origin);
}
// Try the inner stream instead, but this will usually fail.
return _innerStream.Seek(offset, origin);
}
internal void DisableBuffering()
{
_isBuffering = false;
if (_buffer.Length > 0)
{
Flush();
}
}
internal Task DisableBufferingAsync(CancellationToken cancellationToken)
{
_isBuffering = false;
if (_buffer.Length > 0)
{
return FlushAsync(cancellationToken);
}
return Task.CompletedTask;
}
public override void Write(byte[] buffer, int offset, int count)
{
if (_isBuffering)
{
_buffer.Write(buffer, offset, count);
}
else
{
_innerStream.Write(buffer, offset, count);
}
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (_isBuffering)
{
return _buffer.WriteAsync(buffer, offset, count, cancellationToken);
}
else
{
return _innerStream.WriteAsync(buffer, offset, count, cancellationToken);
}
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
if (_isBuffering)
{
return _buffer.BeginWrite(buffer, offset, count, callback, state);
}
else
{
return _innerStream.BeginWrite(buffer, offset, count, callback, state);
}
}
public override void EndWrite(IAsyncResult asyncResult)
{
if (_isBuffering)
{
_buffer.EndWrite(asyncResult);
}
else
{
_innerStream.EndWrite(asyncResult);
}
}
public override void Flush()
{
_isBuffering = false;
if (_buffer.Length > 0)
{
_buffer.Seek(0, SeekOrigin.Begin);
_buffer.CopyTo(_innerStream);
_buffer.Seek(0, SeekOrigin.Begin);
_buffer.SetLength(0);
}
_innerStream.Flush();
}
public override async Task FlushAsync(CancellationToken cancellationToken)
{
_isBuffering = false;
if (_buffer.Length > 0)
{
_buffer.Seek(0, SeekOrigin.Begin);
await _buffer.CopyToAsync(_innerStream, 1024 * 16, cancellationToken);
_buffer.Seek(0, SeekOrigin.Begin);
_buffer.SetLength(0);
}
await _innerStream.FlushAsync(cancellationToken);
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException("This Stream only supports Write operations.");
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.Buffering/HttpBufferingFeature.cs
================================================
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Buffering
{
internal class HttpBufferingFeature : IHttpBufferingFeature
{
private readonly BufferingWriteStream _buffer;
private readonly IHttpBufferingFeature _innerFeature;
internal HttpBufferingFeature(BufferingWriteStream buffer, IHttpBufferingFeature innerFeature)
{
_buffer = buffer;
_innerFeature = innerFeature;
}
public void DisableRequestBuffering()
{
_innerFeature?.DisableRequestBuffering();
}
public void DisableResponseBuffering()
{
_buffer.DisableBuffering();
_innerFeature?.DisableResponseBuffering();
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.Buffering/Microsoft.AspNetCore.Buffering.csproj
================================================
$(ExperimentalVersionPrefix)$(ExperimentalVersionSuffix)false$(ExperimentalPackageVersion)ASP.NET Core middleware for buffering response bodies.netstandard2.0$(NoWarn);CS1591trueaspnetcore;buffer;buffering
================================================
FILE: src/Microsoft.AspNetCore.Buffering/ResponseBufferingMiddleware.cs
================================================
// 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.Http;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Buffering
{
public class ResponseBufferingMiddleware
{
private readonly RequestDelegate _next;
public ResponseBufferingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
var originalResponseBody = httpContext.Response.Body;
// no-op if buffering is already available.
if (originalResponseBody.CanSeek)
{
await _next(httpContext);
return;
}
var originalBufferingFeature = httpContext.Features.Get();
var originalSendFileFeature = httpContext.Features.Get();
try
{
// Shim the response stream
var bufferStream = new BufferingWriteStream(originalResponseBody);
httpContext.Response.Body = bufferStream;
httpContext.Features.Set(new HttpBufferingFeature(bufferStream, originalBufferingFeature));
if (originalSendFileFeature != null)
{
httpContext.Features.Set(new SendFileFeatureWrapper(originalSendFileFeature, bufferStream));
}
await _next(httpContext);
// If we're still buffered, set the content-length header and flush the buffer.
// Only if the content-length header is not already set, and some content was buffered.
if (!httpContext.Response.HasStarted && bufferStream.CanSeek && bufferStream.Length > 0)
{
if (!httpContext.Response.ContentLength.HasValue)
{
httpContext.Response.ContentLength = bufferStream.Length;
}
await bufferStream.FlushAsync();
}
}
finally
{
// undo everything
httpContext.Features.Set(originalBufferingFeature);
httpContext.Features.Set(originalSendFileFeature);
httpContext.Response.Body = originalResponseBody;
}
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.Buffering/ResponseBufferingMiddlewareExtensions.cs
================================================
// 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.Buffering;
namespace Microsoft.AspNetCore.Builder
{
public static class ResponseBufferingMiddlewareExtensions
{
///
/// Enables full buffering of response bodies. This can be disabled on a per request basis using IHttpBufferingFeature.
///
///
///
public static IApplicationBuilder UseResponseBuffering(this IApplicationBuilder builder)
{
return builder.UseMiddleware();
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.Buffering/SendFileFeatureWrapper.cs
================================================
// 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 Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Buffering
{
internal class SendFileFeatureWrapper : IHttpSendFileFeature
{
private readonly IHttpSendFileFeature _originalSendFileFeature;
private readonly BufferingWriteStream _bufferStream;
public SendFileFeatureWrapper(IHttpSendFileFeature originalSendFileFeature, BufferingWriteStream bufferStream)
{
_originalSendFileFeature = originalSendFileFeature;
_bufferStream = bufferStream;
}
// Flush and disable the buffer if anyone tries to call the SendFile feature.
public async Task SendFileAsync(string path, long offset, long? length, CancellationToken cancellation)
{
await _bufferStream.DisableBufferingAsync(cancellation);
await _originalSendFileFeature.SendFileAsync(path, offset, length, cancellation);
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HostFiltering/HostFilteringBuilderExtensions.cs
================================================
// 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.HostFiltering;
namespace Microsoft.AspNetCore.Builder
{
///
/// Extension methods for the HostFiltering middleware.
///
public static class HostFilteringBuilderExtensions
{
///
/// Adds middleware for filtering requests by allowed host headers. Invalid requests will be rejected with a
/// 400 status code.
///
/// The instance this method extends.
/// The original .
public static IApplicationBuilder UseHostFiltering(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
app.UseMiddleware();
return app;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HostFiltering/HostFilteringMiddleware.cs
================================================
// 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;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.HostFiltering
{
///
/// A middleware used to filter requests by their Host header.
///
public class HostFilteringMiddleware
{
// Matches Http.Sys.
private static readonly byte[] DefaultResponse = Encoding.ASCII.GetBytes(
"\r\n"
+ "Bad Request\r\n"
+ " HEAD >\r\n"
+ "
Bad Request - Invalid Hostname
\r\n"
+ "
HTTP Error 400. The request hostname is invalid.
\r\n"
+ "");
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private readonly IOptionsMonitor _optionsMonitor;
private HostFilteringOptions _options;
private IList _allowedHosts;
private bool? _allowAnyNonEmptyHost;
///
/// A middleware used to filter requests by their Host header.
///
///
///
///
public HostFilteringMiddleware(RequestDelegate next, ILogger logger,
IOptionsMonitor optionsMonitor)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_optionsMonitor = optionsMonitor ?? throw new ArgumentNullException(nameof(optionsMonitor));
_options = _optionsMonitor.CurrentValue;
_optionsMonitor.OnChange(options =>
{
// Clear the cached settings so the next EnsureConfigured will re-evaluate.
_options = options;
_allowedHosts = new List();
_allowAnyNonEmptyHost = null;
});
}
///
/// Processes requests
///
///
///
public Task Invoke(HttpContext context)
{
var allowedHosts = EnsureConfigured();
if (!CheckHost(context, allowedHosts))
{
context.Response.StatusCode = 400;
if (_options.IncludeFailureMessage)
{
context.Response.ContentLength = DefaultResponse.Length;
context.Response.ContentType = "text/html";
return context.Response.Body.WriteAsync(DefaultResponse, 0, DefaultResponse.Length);
}
return Task.CompletedTask;
}
return _next(context);
}
private IList EnsureConfigured()
{
if (_allowAnyNonEmptyHost == true || _allowedHosts?.Count > 0)
{
return _allowedHosts;
}
var allowedHosts = new List();
if (_options.AllowedHosts?.Count > 0 && !TryProcessHosts(_options.AllowedHosts, allowedHosts))
{
_logger.LogDebug("Wildcard detected, all requests with hosts will be allowed.");
_allowedHosts = allowedHosts;
_allowAnyNonEmptyHost = true;
return _allowedHosts;
}
if (allowedHosts.Count == 0)
{
throw new InvalidOperationException("No allowed hosts were configured.");
}
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug("Allowed hosts: {Hosts}", string.Join("; ", allowedHosts));
}
_allowedHosts = allowedHosts;
return _allowedHosts;
}
// returns false if any wildcards were found
private bool TryProcessHosts(IEnumerable incoming, IList results)
{
foreach (var entry in incoming)
{
// Punycode. Http.Sys requires you to register Unicode hosts, but the headers contain punycode.
var host = new HostString(entry).ToUriComponent();
if (IsTopLevelWildcard(host))
{
// Disable filtering
return false;
}
if (!results.Contains(host, StringSegmentComparer.OrdinalIgnoreCase))
{
results.Add(host);
}
}
return true;
}
private bool IsTopLevelWildcard(string host)
{
return (string.Equals("*", host, StringComparison.Ordinal) // HttpSys wildcard
|| string.Equals("[::]", host, StringComparison.Ordinal) // Kestrel wildcard, IPv6 Any
|| string.Equals("0.0.0.0", host, StringComparison.Ordinal)); // IPv4 Any
}
// This does not duplicate format validations that are expected to be performed by the host.
private bool CheckHost(HttpContext context, IList allowedHosts)
{
var host = new StringSegment(context.Request.Headers[HeaderNames.Host].ToString()).Trim();
if (StringSegment.IsNullOrEmpty(host))
{
// Http/1.0 does not require the host header.
// Http/1.1 requires the header but the value may be empty.
if (!_options.AllowEmptyHosts)
{
_logger.LogInformation("{Protocol} request rejected due to missing or empty host header.", context.Request.Protocol);
return false;
}
_logger.LogDebug("{Protocol} request allowed with missing or empty host header.", context.Request.Protocol);
return true;
}
if (_allowAnyNonEmptyHost == true)
{
_logger.LogTrace("All hosts are allowed.");
return true;
}
if (HostString.MatchesAny(host, allowedHosts))
{
_logger.LogTrace("The host '{Host}' matches an allowed host.", host);
return true;
}
_logger.LogInformation("The host '{Host}' does not match an allowed host.", host);
return false;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HostFiltering/HostFilteringOptions.cs
================================================
// 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;
namespace Microsoft.AspNetCore.HostFiltering
{
///
/// Options for the HostFiltering middleware
///
public class HostFilteringOptions
{
///
/// The hosts headers that are allowed to access this site. At least one value is required.
///
///
///
/// Port numbers must be excluded.
/// A top level wildcard "*" allows all non-empty hosts.
/// Subdomain wildcards are permitted. E.g. "*.example.com" matches subdomains like foo.example.com,
/// but not the parent domain example.com.
/// Unicode host names are allowed but will be converted to punycode for matching.
/// IPv6 addresses must include their bounding brackets and be in their normalized form.
///
///
public IList AllowedHosts { get; set; } = new List();
///
/// Indicates if requests without hosts are allowed. The default is true.
///
///
/// HTTP/1.0 does not require a host header.
/// Http/1.1 requires a host header, but says the value may be empty.
///
public bool AllowEmptyHosts { get; set; } = true;
// Note if this were disabled then things like the status code middleware may try to re-execute
// the request. This is a low level protocol violation, pretty error pages should not be required.
///
/// Indicates if the 400 response should include a default message or be empty. This is enabled by default.
///
public bool IncludeFailureMessage { get; set; } = true;
}
}
================================================
FILE: src/Microsoft.AspNetCore.HostFiltering/HostFilteringServicesExtensions.cs
================================================
// 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.HostFiltering;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Builder
{
///
/// Extension methods for the host filtering middleware.
///
public static class HostFilteringServicesExtensions
{
///
/// Adds services and options for the host filtering middleware.
///
/// The for adding services.
/// A delegate to configure the .
///
public static IServiceCollection AddHostFiltering(this IServiceCollection services, Action configureOptions)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (configureOptions == null)
{
throw new ArgumentNullException(nameof(configureOptions));
}
services.Configure(configureOptions);
return services;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HostFiltering/Microsoft.AspNetCore.HostFiltering.csproj
================================================
ASP.NET Core middleware for filtering out requests with unknown HTTP host headers.
netstandard2.0trueaspnetcore
================================================
FILE: src/Microsoft.AspNetCore.HostFiltering/baseline.netcore.json
================================================
{
"AssemblyIdentity": "Microsoft.AspNetCore.HostFiltering, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "logger",
"Type": "Microsoft.Extensions.Logging.ILogger"
},
{
"Name": "optionsMonitor",
"Type": "Microsoft.Extensions.Options.IOptionsMonitor"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HostFiltering.HostFilteringOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_AllowedHosts",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_AllowedHosts",
"Parameters": [
{
"Name": "value",
"Type": "System.Collections.Generic.IList"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_AllowEmptyHosts",
"Parameters": [],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_AllowEmptyHosts",
"Parameters": [
{
"Name": "value",
"Type": "System.Boolean"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_IncludeFailureMessage",
"Parameters": [],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_IncludeFailureMessage",
"Parameters": [
{
"Name": "value",
"Type": "System.Boolean"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HostFilteringBuilderExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseHostFiltering",
"Parameters": [
{
"Name": "app",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HostFilteringServicesExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "AddHostFiltering",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
},
{
"Name": "configureOptions",
"Type": "System.Action"
}
],
"ReturnType": "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeaders.cs
================================================
// 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.HttpOverrides
{
[Flags]
public enum ForwardedHeaders
{
None = 0,
XForwardedFor = 1 << 0,
XForwardedHost = 1 << 1,
XForwardedProto = 1 << 2,
All = XForwardedFor | XForwardedHost | XForwardedProto
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersDefaults.cs
================================================
// 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.HttpOverrides
{
///
/// Default values related to middleware
///
///
public static class ForwardedHeadersDefaults
{
///
/// X-Forwarded-For
///
public static string XForwardedForHeaderName { get; } = "X-Forwarded-For";
///
/// X-Forwarded-Host
///
public static string XForwardedHostHeaderName { get; } = "X-Forwarded-Host";
///
/// X-Forwarded-Proto
///
public static string XForwardedProtoHeaderName { get; } = "X-Forwarded-Proto";
///
/// X-Original-For
///
public static string XOriginalForHeaderName { get; } = "X-Original-For";
///
/// X-Original-Host
///
public static string XOriginalHostHeaderName { get; } = "X-Original-Host";
///
/// X-Original-Proto
///
public static string XOriginalProtoHeaderName { get; } = "X-Original-Proto";
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersExtensions.cs
================================================
// 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.HttpOverrides;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
public static class ForwardedHeadersExtensions
{
///
/// Forwards proxied headers onto current request
///
///
///
public static IApplicationBuilder UseForwardedHeaders(this IApplicationBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
return builder.UseMiddleware();
}
///
/// Forwards proxied headers onto current request
///
///
/// Enables the different forwarding options.
///
public static IApplicationBuilder UseForwardedHeaders(this IApplicationBuilder builder, ForwardedHeadersOptions options)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return builder.UseMiddleware(Options.Create(options));
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersMiddleware.cs
================================================
// 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.Net;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.HttpOverrides
{
public class ForwardedHeadersMiddleware
{
private static readonly bool[] HostCharValidity = new bool[127];
private static readonly bool[] SchemeCharValidity = new bool[123];
private readonly ForwardedHeadersOptions _options;
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private bool _allowAllHosts;
private IList _allowedHosts;
static ForwardedHeadersMiddleware()
{
// RFC 3986 scheme = ALPHA * (ALPHA / DIGIT / "+" / "-" / ".")
SchemeCharValidity['+'] = true;
SchemeCharValidity['-'] = true;
SchemeCharValidity['.'] = true;
// Host Matches Http.Sys and Kestrel
// Host Matches RFC 3986 except "*" / "+" / "," / ";" / "=" and "%" HEXDIG HEXDIG which are not allowed by Http.Sys
HostCharValidity['!'] = true;
HostCharValidity['$'] = true;
HostCharValidity['&'] = true;
HostCharValidity['\''] = true;
HostCharValidity['('] = true;
HostCharValidity[')'] = true;
HostCharValidity['-'] = true;
HostCharValidity['.'] = true;
HostCharValidity['_'] = true;
HostCharValidity['~'] = true;
for (var ch = '0'; ch <= '9'; ch++)
{
SchemeCharValidity[ch] = true;
HostCharValidity[ch] = true;
}
for (var ch = 'A'; ch <= 'Z'; ch++)
{
SchemeCharValidity[ch] = true;
HostCharValidity[ch] = true;
}
for (var ch = 'a'; ch <= 'z'; ch++)
{
SchemeCharValidity[ch] = true;
HostCharValidity[ch] = true;
}
}
public ForwardedHeadersMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptions options)
{
if (next == null)
{
throw new ArgumentNullException(nameof(next));
}
if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// Make sure required options is not null or whitespace
EnsureOptionNotNullorWhitespace(options.Value.ForwardedForHeaderName, nameof(options.Value.ForwardedForHeaderName));
EnsureOptionNotNullorWhitespace(options.Value.ForwardedHostHeaderName, nameof(options.Value.ForwardedHostHeaderName));
EnsureOptionNotNullorWhitespace(options.Value.ForwardedProtoHeaderName, nameof(options.Value.ForwardedProtoHeaderName));
EnsureOptionNotNullorWhitespace(options.Value.OriginalForHeaderName, nameof(options.Value.OriginalForHeaderName));
EnsureOptionNotNullorWhitespace(options.Value.OriginalHostHeaderName, nameof(options.Value.OriginalHostHeaderName));
EnsureOptionNotNullorWhitespace(options.Value.OriginalProtoHeaderName, nameof(options.Value.OriginalProtoHeaderName));
_options = options.Value;
_logger = loggerFactory.CreateLogger();
_next = next;
PreProcessHosts();
}
private static void EnsureOptionNotNullorWhitespace(string value, string propertyName)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException($"options.{propertyName} is required", "options");
}
}
private void PreProcessHosts()
{
if (_options.AllowedHosts == null || _options.AllowedHosts.Count == 0)
{
_allowAllHosts = true;
return;
}
var allowedHosts = new List();
foreach (var entry in _options.AllowedHosts)
{
// Punycode. Http.Sys requires you to register Unicode hosts, but the headers contain punycode.
var host = new HostString(entry).ToUriComponent();
if (IsTopLevelWildcard(host))
{
// Disable filtering
_allowAllHosts = true;
return;
}
if (!allowedHosts.Contains(host, StringSegmentComparer.OrdinalIgnoreCase))
{
allowedHosts.Add(host);
}
}
_allowedHosts = allowedHosts;
}
private bool IsTopLevelWildcard(string host)
{
return (string.Equals("*", host, StringComparison.Ordinal) // HttpSys wildcard
|| string.Equals("[::]", host, StringComparison.Ordinal) // Kestrel wildcard, IPv6 Any
|| string.Equals("0.0.0.0", host, StringComparison.Ordinal)); // IPv4 Any
}
public Task Invoke(HttpContext context)
{
ApplyForwarders(context);
return _next(context);
}
public void ApplyForwarders(HttpContext context)
{
// Gather expected headers.
string[] forwardedFor = null, forwardedProto = null, forwardedHost = null;
bool checkFor = false, checkProto = false, checkHost = false;
int entryCount = 0;
if ((_options.ForwardedHeaders & ForwardedHeaders.XForwardedFor) == ForwardedHeaders.XForwardedFor)
{
checkFor = true;
forwardedFor = context.Request.Headers.GetCommaSeparatedValues(_options.ForwardedForHeaderName);
entryCount = Math.Max(forwardedFor.Length, entryCount);
}
if ((_options.ForwardedHeaders & ForwardedHeaders.XForwardedProto) == ForwardedHeaders.XForwardedProto)
{
checkProto = true;
forwardedProto = context.Request.Headers.GetCommaSeparatedValues(_options.ForwardedProtoHeaderName);
if (_options.RequireHeaderSymmetry && checkFor && forwardedFor.Length != forwardedProto.Length)
{
_logger.LogWarning(1, "Parameter count mismatch between X-Forwarded-For and X-Forwarded-Proto.");
return;
}
entryCount = Math.Max(forwardedProto.Length, entryCount);
}
if ((_options.ForwardedHeaders & ForwardedHeaders.XForwardedHost) == ForwardedHeaders.XForwardedHost)
{
checkHost = true;
forwardedHost = context.Request.Headers.GetCommaSeparatedValues(_options.ForwardedHostHeaderName);
if (_options.RequireHeaderSymmetry
&& ((checkFor && forwardedFor.Length != forwardedHost.Length)
|| (checkProto && forwardedProto.Length != forwardedHost.Length)))
{
_logger.LogWarning(1, "Parameter count mismatch between X-Forwarded-Host and X-Forwarded-For or X-Forwarded-Proto.");
return;
}
entryCount = Math.Max(forwardedHost.Length, entryCount);
}
// Apply ForwardLimit, if any
if (_options.ForwardLimit.HasValue && entryCount > _options.ForwardLimit)
{
entryCount = _options.ForwardLimit.Value;
}
// Group the data together.
var sets = new SetOfForwarders[entryCount];
for (int i = 0; i < sets.Length; i++)
{
// They get processed in reverse order, right to left.
var set = new SetOfForwarders();
if (checkFor && i < forwardedFor.Length)
{
set.IpAndPortText = forwardedFor[forwardedFor.Length - i - 1];
}
if (checkProto && i < forwardedProto.Length)
{
set.Scheme = forwardedProto[forwardedProto.Length - i - 1];
}
if (checkHost && i < forwardedHost.Length)
{
set.Host = forwardedHost[forwardedHost.Length - i - 1];
}
sets[i] = set;
}
// Gather initial values
var connection = context.Connection;
var request = context.Request;
var currentValues = new SetOfForwarders()
{
RemoteIpAndPort = connection.RemoteIpAddress != null ? new IPEndPoint(connection.RemoteIpAddress, connection.RemotePort) : null,
// Host and Scheme initial values are never inspected, no need to set them here.
};
var checkKnownIps = _options.KnownNetworks.Count > 0 || _options.KnownProxies.Count > 0;
bool applyChanges = false;
int entriesConsumed = 0;
for ( ; entriesConsumed < sets.Length; entriesConsumed++)
{
var set = sets[entriesConsumed];
if (checkFor)
{
// For the first instance, allow remoteIp to be null for servers that don't support it natively.
if (currentValues.RemoteIpAndPort != null && checkKnownIps && !CheckKnownAddress(currentValues.RemoteIpAndPort.Address))
{
// Stop at the first unknown remote IP, but still apply changes processed so far.
_logger.LogDebug(1, "Unknown proxy: {RemoteIpAndPort}", currentValues.RemoteIpAndPort);
break;
}
IPEndPoint parsedEndPoint;
if (IPEndPointParser.TryParse(set.IpAndPortText, out parsedEndPoint))
{
applyChanges = true;
set.RemoteIpAndPort = parsedEndPoint;
currentValues.IpAndPortText = set.IpAndPortText;
currentValues.RemoteIpAndPort = set.RemoteIpAndPort;
}
else if (!string.IsNullOrEmpty(set.IpAndPortText))
{
// Stop at the first unparsable IP, but still apply changes processed so far.
_logger.LogDebug(1, "Unparsable IP: {IpAndPortText}", set.IpAndPortText);
break;
}
else if (_options.RequireHeaderSymmetry)
{
_logger.LogWarning(2, "Missing forwarded IPAddress.");
return;
}
}
if (checkProto)
{
if (!string.IsNullOrEmpty(set.Scheme) && TryValidateScheme(set.Scheme))
{
applyChanges = true;
currentValues.Scheme = set.Scheme;
}
else if (_options.RequireHeaderSymmetry)
{
_logger.LogWarning(3, $"Forwarded scheme is not present, this is required by {nameof(_options.RequireHeaderSymmetry)}");
return;
}
}
if (checkHost)
{
if (!string.IsNullOrEmpty(set.Host) && TryValidateHost(set.Host)
&& (_allowAllHosts || HostString.MatchesAny(set.Host, _allowedHosts)))
{
applyChanges = true;
currentValues.Host = set.Host;
}
else if (_options.RequireHeaderSymmetry)
{
_logger.LogWarning(4, $"Incorrect number of x-forwarded-host header values, see {nameof(_options.RequireHeaderSymmetry)}.");
return;
}
}
}
if (applyChanges)
{
if (checkFor && currentValues.RemoteIpAndPort != null)
{
if (connection.RemoteIpAddress != null)
{
// Save the original
request.Headers[_options.OriginalForHeaderName] = new IPEndPoint(connection.RemoteIpAddress, connection.RemotePort).ToString();
}
if (forwardedFor.Length > entriesConsumed)
{
// Truncate the consumed header values
request.Headers[_options.ForwardedForHeaderName] = forwardedFor.Take(forwardedFor.Length - entriesConsumed).ToArray();
}
else
{
// All values were consumed
request.Headers.Remove(_options.ForwardedForHeaderName);
}
connection.RemoteIpAddress = currentValues.RemoteIpAndPort.Address;
connection.RemotePort = currentValues.RemoteIpAndPort.Port;
}
if (checkProto && currentValues.Scheme != null)
{
// Save the original
request.Headers[_options.OriginalProtoHeaderName] = request.Scheme;
if (forwardedProto.Length > entriesConsumed)
{
// Truncate the consumed header values
request.Headers[_options.ForwardedProtoHeaderName] = forwardedProto.Take(forwardedProto.Length - entriesConsumed).ToArray();
}
else
{
// All values were consumed
request.Headers.Remove(_options.ForwardedProtoHeaderName);
}
request.Scheme = currentValues.Scheme;
}
if (checkHost && currentValues.Host != null)
{
// Save the original
request.Headers[_options.OriginalHostHeaderName] = request.Host.ToString();
if (forwardedHost.Length > entriesConsumed)
{
// Truncate the consumed header values
request.Headers[_options.ForwardedHostHeaderName] = forwardedHost.Take(forwardedHost.Length - entriesConsumed).ToArray();
}
else
{
// All values were consumed
request.Headers.Remove(_options.ForwardedHostHeaderName);
}
request.Host = HostString.FromUriComponent(currentValues.Host);
}
}
}
private bool CheckKnownAddress(IPAddress address)
{
if (address.IsIPv4MappedToIPv6)
{
var ipv4Address = address.MapToIPv4();
if (CheckKnownAddress(ipv4Address))
{
return true;
}
}
if (_options.KnownProxies.Contains(address))
{
return true;
}
foreach (var network in _options.KnownNetworks)
{
if (network.Contains(address))
{
return true;
}
}
return false;
}
private struct SetOfForwarders
{
public string IpAndPortText;
public IPEndPoint RemoteIpAndPort;
public string Host;
public string Scheme;
}
// Empty was checked for by the caller
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryValidateScheme(string scheme)
{
for (var i = 0; i < scheme.Length; i++)
{
if (!IsValidSchemeChar(scheme[i]))
{
return false;
}
}
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsValidSchemeChar(char ch)
{
return ch < SchemeCharValidity.Length && SchemeCharValidity[ch];
}
// Empty was checked for by the caller
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryValidateHost(string host)
{
if (host[0] == '[')
{
return TryValidateIPv6Host(host);
}
if (host[0] == ':')
{
// Only a port
return false;
}
var i = 0;
for (; i < host.Length; i++)
{
if (!IsValidHostChar(host[i]))
{
break;
}
}
return TryValidateHostPort(host, i);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsValidHostChar(char ch)
{
return ch < HostCharValidity.Length && HostCharValidity[ch];
}
// The lead '[' was already checked
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryValidateIPv6Host(string hostText)
{
for (var i = 1; i < hostText.Length; i++)
{
var ch = hostText[i];
if (ch == ']')
{
// [::1] is the shortest valid IPv6 host
if (i < 4)
{
return false;
}
return TryValidateHostPort(hostText, i + 1);
}
if (!IsHex(ch) && ch != ':' && ch != '.')
{
return false;
}
}
// Must contain a ']'
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool TryValidateHostPort(string hostText, int offset)
{
if (offset == hostText.Length)
{
// No port
return true;
}
if (hostText[offset] != ':' || hostText.Length == offset + 1)
{
// Must have at least one number after the colon if present.
return false;
}
for (var i = offset + 1; i < hostText.Length; i++)
{
if (!IsNumeric(hostText[i]))
{
return false;
}
}
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsNumeric(char ch)
{
return '0' <= ch && ch <= '9';
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool IsHex(char ch)
{
return IsNumeric(ch)
|| ('a' <= ch && ch <= 'f')
|| ('A' <= ch && ch <= 'F');
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersOptions.cs
================================================
// 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;
using Microsoft.AspNetCore.HttpOverrides;
namespace Microsoft.AspNetCore.Builder
{
public class ForwardedHeadersOptions
{
///
/// Use this header instead of
///
///
public string ForwardedForHeaderName { get; set; } = ForwardedHeadersDefaults.XForwardedForHeaderName;
///
/// Use this header instead of
///
///
public string ForwardedHostHeaderName { get; set; } = ForwardedHeadersDefaults.XForwardedHostHeaderName;
///
/// Use this header instead of
///
///
public string ForwardedProtoHeaderName { get; set; } = ForwardedHeadersDefaults.XForwardedProtoHeaderName;
///
/// Use this header instead of
///
///
public string OriginalForHeaderName { get; set; } = ForwardedHeadersDefaults.XOriginalForHeaderName;
///
/// Use this header instead of
///
///
public string OriginalHostHeaderName { get; set; } = ForwardedHeadersDefaults.XOriginalHostHeaderName;
///
/// Use this header instead of
///
///
public string OriginalProtoHeaderName { get; set; } = ForwardedHeadersDefaults.XOriginalProtoHeaderName;
///
/// Identifies which forwarders should be processed.
///
public ForwardedHeaders ForwardedHeaders { get; set; }
///
/// Limits the number of entries in the headers that will be processed. The default value is 1.
/// Set to null to disable the limit, but this should only be done if
/// KnownProxies or KnownNetworks are configured.
///
public int? ForwardLimit { get; set; } = 1;
///
/// Addresses of known proxies to accept forwarded headers from.
///
public IList KnownProxies { get; } = new List() { IPAddress.IPv6Loopback };
///
/// Address ranges of known proxies to accept forwarded headers from.
///
public IList KnownNetworks { get; } = new List() { new IPNetwork(IPAddress.Loopback, 8) };
///
/// The allowed values from x-forwarded-host. If the list is empty then all hosts are allowed.
/// Failing to restrict this these values may allow an attacker to spoof links generated by your service.
///
///
///
/// Port numbers must be excluded.
/// A top level wildcard "*" allows all non-empty hosts.
/// Subdomain wildcards are permitted. E.g. "*.example.com" matches subdomains like foo.example.com,
/// but not the parent domain example.com.
/// Unicode host names are allowed but will be converted to punycode for matching.
/// IPv6 addresses must include their bounding brackets and be in their normalized form.
///
///
public IList AllowedHosts { get; set; } = new List();
///
/// Require the number of header values to be in sync between the different headers being processed.
/// The default is 'false'.
///
public bool RequireHeaderSymmetry { get; set; } = false;
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/HttpMethodOverrideExtensions.cs
================================================
// 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.HttpOverrides;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
public static class HttpMethodOverrideExtensions
{
///
/// Allows incoming POST request to override method type with type specified in header.
///
/// The instance this method extends.
public static IApplicationBuilder UseHttpMethodOverride(this IApplicationBuilder builder)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
return builder.UseMiddleware();
}
///
/// Allows incoming POST request to override method type with type specified in form.
///
/// The instance this method extends.
/// The .
public static IApplicationBuilder UseHttpMethodOverride(this IApplicationBuilder builder, HttpMethodOverrideOptions options)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
return builder.UseMiddleware(Options.Create(options));
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/HttpMethodOverrideMiddleware.cs
================================================
// 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.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.HttpOverrides
{
public class HttpMethodOverrideMiddleware
{
private const string xHttpMethodOverride = "X-Http-Method-Override";
private readonly RequestDelegate _next;
private readonly HttpMethodOverrideOptions _options;
public HttpMethodOverrideMiddleware(RequestDelegate next, IOptions options)
{
if (next == null)
{
throw new ArgumentNullException(nameof(next));
}
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
_next = next;
_options = options.Value;
}
public async Task Invoke(HttpContext context)
{
if (string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
{
if (_options.FormFieldName != null)
{
if (context.Request.HasFormContentType)
{
var form = await context.Request.ReadFormAsync();
var methodType = form[_options.FormFieldName];
if (!string.IsNullOrEmpty(methodType))
{
context.Request.Method = methodType;
}
}
}
else
{
var xHttpMethodOverrideValue = context.Request.Headers[xHttpMethodOverride];
if (!string.IsNullOrEmpty(xHttpMethodOverrideValue))
{
context.Request.Method = xHttpMethodOverrideValue;
}
}
}
await _next(context);
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/HttpMethodOverrideOptions.cs
================================================
// 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.Builder
{
public class HttpMethodOverrideOptions
{
///
/// Denotes the form element that contains the name of the resulting method type.
/// If not set the X-Http-Method-Override header will be used.
///
public string FormFieldName { get; set; }
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/IPNetwork.cs
================================================
// 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;
namespace Microsoft.AspNetCore.HttpOverrides
{
public class IPNetwork
{
public IPNetwork(IPAddress prefix, int prefixLength)
{
Prefix = prefix;
PrefixLength = prefixLength;
PrefixBytes = Prefix.GetAddressBytes();
Mask = CreateMask();
}
public IPAddress Prefix { get; }
private byte[] PrefixBytes { get; }
///
/// The CIDR notation of the subnet mask
///
public int PrefixLength { get; }
private byte[] Mask { get; }
public bool Contains(IPAddress address)
{
if (Prefix.AddressFamily != address.AddressFamily)
{
return false;
}
var addressBytes = address.GetAddressBytes();
for (int i = 0; i < PrefixBytes.Length && Mask[i] != 0; i++)
{
if (PrefixBytes[i] != (addressBytes[i] & Mask[i]))
{
return false;
}
}
return true;
}
private byte[] CreateMask()
{
var mask = new byte[PrefixBytes.Length];
int remainingBits = PrefixLength;
int i = 0;
while (remainingBits >= 8)
{
mask[i] = 0xFF;
i++;
remainingBits -= 8;
}
if (remainingBits > 0)
{
mask[i] = (byte)(0xFF << (8 - remainingBits));
}
return mask;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/Internal/IPEndPointParser.cs
================================================
// 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.Net;
namespace Microsoft.AspNetCore.HttpOverrides.Internal
{
public static class IPEndPointParser
{
public static bool TryParse(string addressWithPort, out IPEndPoint endpoint)
{
string addressPart = null;
string portPart = null;
IPAddress address;
endpoint = null;
if (string.IsNullOrEmpty(addressWithPort))
{
return false;
}
var lastColonIndex = addressWithPort.LastIndexOf(':');
if (lastColonIndex > 0)
{
// IPv4 with port or IPv6
var closingIndex = addressWithPort.LastIndexOf(']');
if (closingIndex > 0)
{
// IPv6 with brackets
addressPart = addressWithPort.Substring(1, closingIndex - 1);
if (closingIndex < lastColonIndex)
{
// IPv6 with port [::1]:80
portPart = addressWithPort.Substring(lastColonIndex + 1);
}
}
else
{
// IPv6 without port or IPv4
var firstColonIndex = addressWithPort.IndexOf(':');
if (firstColonIndex != lastColonIndex)
{
// IPv6 ::1
addressPart = addressWithPort;
}
else
{
// IPv4 with port 127.0.0.1:123
addressPart = addressWithPort.Substring(0, firstColonIndex);
portPart = addressWithPort.Substring(firstColonIndex + 1);
}
}
}
else
{
// IPv4 without port
addressPart = addressWithPort;
}
if (IPAddress.TryParse(addressPart, out address))
{
if (portPart != null)
{
int port;
if (int.TryParse(portPart, NumberStyles.None, CultureInfo.InvariantCulture, out port))
{
endpoint = new IPEndPoint(address, port);
return true;
}
return false;
}
endpoint = new IPEndPoint(address, 0);
return true;
}
return false;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/Microsoft.AspNetCore.HttpOverrides.csproj
================================================
ASP.NET Core basic middleware for supporting HTTP method overrides. Includes:
* X-Forwarded-* headers to forward headers from a proxy.
* HTTP method override header.netstandard2.0$(NoWarn);CS1591trueaspnetcore;proxy;headers;xforwarded
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/baseline.net45.json
================================================
{
"AssemblyIdentity": "Microsoft.AspNetCore.HttpOverrides, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.Builder.ForwardedHeadersExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseForwardedHeaders",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseForwardedHeaders",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
},
{
"Name": "options",
"Type": "Microsoft.AspNetCore.Builder.ForwardedHeadersOptions"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.ForwardedHeadersOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_ForwardedHeaders",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardedHeaders",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ForwardLimit",
"Parameters": [],
"ReturnType": "System.Nullable",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardLimit",
"Parameters": [
{
"Name": "value",
"Type": "System.Nullable"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_KnownProxies",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_KnownNetworks",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_RequireHeaderSymmetry",
"Parameters": [],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_RequireHeaderSymmetry",
"Parameters": [
{
"Name": "value",
"Type": "System.Boolean"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HttpMethodOverrideExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseHttpMethodOverride",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseHttpMethodOverride",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
},
{
"Name": "options",
"Type": "Microsoft.AspNetCore.Builder.HttpMethodOverrideOptions"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HttpMethodOverrideOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_FormFieldName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_FormFieldName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders",
"Visibility": "Public",
"Kind": "Enumeration",
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "None",
"Parameters": [],
"GenericParameter": [],
"Literal": "0"
},
{
"Kind": "Field",
"Name": "XForwardedFor",
"Parameters": [],
"GenericParameter": [],
"Literal": "1"
},
{
"Kind": "Field",
"Name": "XForwardedHost",
"Parameters": [],
"GenericParameter": [],
"Literal": "2"
},
{
"Kind": "Field",
"Name": "XForwardedProto",
"Parameters": [],
"GenericParameter": [],
"Literal": "4"
},
{
"Kind": "Field",
"Name": "All",
"Parameters": [],
"GenericParameter": [],
"Literal": "7"
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ApplyForwarders",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "loggerFactory",
"Type": "Microsoft.Extensions.Logging.ILoggerFactory"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.HttpMethodOverrideMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.IPNetwork",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Prefix",
"Parameters": [],
"ReturnType": "System.Net.IPAddress",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_PrefixLength",
"Parameters": [],
"ReturnType": "System.Int32",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Contains",
"Parameters": [
{
"Name": "address",
"Type": "System.Net.IPAddress"
}
],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "prefix",
"Type": "System.Net.IPAddress"
},
{
"Name": "prefixLength",
"Type": "System.Int32"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.Internal.IPEndPointParser",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "TryParse",
"Parameters": [
{
"Name": "addressWithPort",
"Type": "System.String"
},
{
"Name": "endpoint",
"Type": "System.Net.IPEndPoint",
"Direction": "Out"
}
],
"ReturnType": "System.Boolean",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}
================================================
FILE: src/Microsoft.AspNetCore.HttpOverrides/baseline.netcore.json
================================================
{
"AssemblyIdentity": "Microsoft.AspNetCore.HttpOverrides, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.Builder.ForwardedHeadersExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseForwardedHeaders",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseForwardedHeaders",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
},
{
"Name": "options",
"Type": "Microsoft.AspNetCore.Builder.ForwardedHeadersOptions"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.ForwardedHeadersOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_ForwardedForHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardedForHeaderName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ForwardedHostHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardedHostHeaderName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ForwardedProtoHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardedProtoHeaderName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_OriginalForHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_OriginalForHeaderName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_OriginalHostHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_OriginalHostHeaderName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_OriginalProtoHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_OriginalProtoHeaderName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ForwardedHeaders",
"Parameters": [],
"ReturnType": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardedHeaders",
"Parameters": [
{
"Name": "value",
"Type": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ForwardLimit",
"Parameters": [],
"ReturnType": "System.Nullable",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_ForwardLimit",
"Parameters": [
{
"Name": "value",
"Type": "System.Nullable"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_KnownProxies",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_KnownNetworks",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_AllowedHosts",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_AllowedHosts",
"Parameters": [
{
"Name": "value",
"Type": "System.Collections.Generic.IList"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_RequireHeaderSymmetry",
"Parameters": [],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_RequireHeaderSymmetry",
"Parameters": [
{
"Name": "value",
"Type": "System.Boolean"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HttpMethodOverrideExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseHttpMethodOverride",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "UseHttpMethodOverride",
"Parameters": [
{
"Name": "builder",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
},
{
"Name": "options",
"Type": "Microsoft.AspNetCore.Builder.HttpMethodOverrideOptions"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HttpMethodOverrideOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_FormFieldName",
"Parameters": [],
"ReturnType": "System.String",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_FormFieldName",
"Parameters": [
{
"Name": "value",
"Type": "System.String"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders",
"Visibility": "Public",
"Kind": "Enumeration",
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Field",
"Name": "None",
"Parameters": [],
"GenericParameter": [],
"Literal": "0"
},
{
"Kind": "Field",
"Name": "XForwardedFor",
"Parameters": [],
"GenericParameter": [],
"Literal": "1"
},
{
"Kind": "Field",
"Name": "XForwardedHost",
"Parameters": [],
"GenericParameter": [],
"Literal": "2"
},
{
"Kind": "Field",
"Name": "XForwardedProto",
"Parameters": [],
"GenericParameter": [],
"Literal": "4"
},
{
"Kind": "Field",
"Name": "All",
"Parameters": [],
"GenericParameter": [],
"Literal": "7"
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersDefaults",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_XForwardedForHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_XForwardedHostHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_XForwardedProtoHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_XOriginalForHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_XOriginalHostHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_XOriginalProtoHeaderName",
"Parameters": [],
"ReturnType": "System.String",
"Static": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "ApplyForwarders",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "loggerFactory",
"Type": "Microsoft.Extensions.Logging.ILoggerFactory"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.HttpMethodOverrideMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpOverrides.IPNetwork",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_Prefix",
"Parameters": [],
"ReturnType": "System.Net.IPAddress",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_PrefixLength",
"Parameters": [],
"ReturnType": "System.Int32",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "Contains",
"Parameters": [
{
"Name": "address",
"Type": "System.Net.IPAddress"
}
],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "prefix",
"Type": "System.Net.IPAddress"
},
{
"Name": "prefixLength",
"Type": "System.Int32"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HstsBuilderExtensions.cs
================================================
// 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.HttpsPolicy;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Builder
{
///
/// Extension methods for the HSTS middleware.
///
public static class HstsBuilderExtensions
{
///
/// Adds middleware for using HSTS, which adds the Strict-Transport-Security header.
///
/// The instance this method extends.
public static IApplicationBuilder UseHsts(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware();
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HstsMiddleware.cs
================================================
// 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.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy.Internal;
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.HttpsPolicy
{
///
/// Enables HTTP Strict Transport Security (HSTS)
/// See https://tools.ietf.org/html/rfc6797.
///
public class HstsMiddleware
{
private const string IncludeSubDomains = "; includeSubDomains";
private const string Preload = "; preload";
private readonly RequestDelegate _next;
private readonly StringValues _strictTransportSecurityValue;
private readonly IList _excludedHosts;
private readonly ILogger _logger;
///
/// Initialize the HSTS middleware.
///
///
///
///
public HstsMiddleware(RequestDelegate next, IOptions options, ILoggerFactory loggerFactory)
{
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
_next = next ?? throw new ArgumentNullException(nameof(next));
var hstsOptions = options.Value;
var maxAge = Convert.ToInt64(Math.Floor(hstsOptions.MaxAge.TotalSeconds))
.ToString(CultureInfo.InvariantCulture);
var includeSubdomains = hstsOptions.IncludeSubDomains ? IncludeSubDomains : StringSegment.Empty;
var preload = hstsOptions.Preload ? Preload : StringSegment.Empty;
_strictTransportSecurityValue = new StringValues($"max-age={maxAge}{includeSubdomains}{preload}");
_excludedHosts = hstsOptions.ExcludedHosts;
_logger = loggerFactory.CreateLogger();
}
///
/// Initialize the HSTS middleware.
///
///
///
public HstsMiddleware(RequestDelegate next, IOptions options)
: this(next, options, NullLoggerFactory.Instance) { }
///
/// Invoke the middleware.
///
/// The .
///
public Task Invoke(HttpContext context)
{
if (!context.Request.IsHttps)
{
_logger.SkippingInsecure();
return _next(context);
}
if (IsHostExcluded(context.Request.Host.Host))
{
_logger.SkippingExcludedHost(context.Request.Host.Host);
return _next(context);
}
context.Response.Headers[HeaderNames.StrictTransportSecurity] = _strictTransportSecurityValue;
_logger.AddingHstsHeader();
return _next(context);
}
private bool IsHostExcluded(string host)
{
if (_excludedHosts == null)
{
return false;
}
for (var i = 0; i < _excludedHosts.Count; i++)
{
if (string.Equals(host, _excludedHosts[i], StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HstsOptions.cs
================================================
// 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.HttpsPolicy
{
///
/// Options for the Hsts Middleware
///
public class HstsOptions
{
///
/// Sets the max-age parameter of the Strict-Transport-Security header.
///
///
/// Max-age is required; defaults to 30 days.
/// See: https://tools.ietf.org/html/rfc6797#section-6.1.1
///
public TimeSpan MaxAge { get; set; } = TimeSpan.FromDays(30);
///
/// Enables includeSubDomain parameter of the Strict-Transport-Security header.
///
///
/// See: https://tools.ietf.org/html/rfc6797#section-6.1.2
///
public bool IncludeSubDomains { get; set; }
///
/// Sets the preload parameter of the Strict-Transport-Security header.
///
///
/// Preload is not part of the RFC specification, but is supported by web browsers
/// to preload HSTS sites on fresh install. See https://hstspreload.org/.
///
public bool Preload { get; set; }
///
/// A list of host names that will not add the HSTS header.
///
public IList ExcludedHosts { get; } = new List
{
"localhost",
"127.0.0.1", // ipv4
"[::1]" // ipv6
};
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HstsServicesExtensions.cs
================================================
// 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.HttpsPolicy;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Builder
{
///
/// Extension methods for the HSTS middleware.
///
public static class HstsServicesExtensions
{
///
/// Adds HSTS services.
///
/// The for adding services.
/// A delegate to configure the .
///
public static IServiceCollection AddHsts(this IServiceCollection services, Action configureOptions)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (configureOptions == null)
{
throw new ArgumentNullException(nameof(configureOptions));
}
services.Configure(configureOptions);
return services;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionBuilderExtensions.cs
================================================
// 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.Hosting.Server.Features;
using Microsoft.AspNetCore.HttpsPolicy;
namespace Microsoft.AspNetCore.Builder
{
///
/// Extension methods for the HttpsRedirection middleware.
///
public static class HttpsPolicyBuilderExtensions
{
///
/// Adds middleware for redirecting HTTP Requests to HTTPS.
///
/// The instance this method extends.
/// The for HttpsRedirection.
public static IApplicationBuilder UseHttpsRedirection(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
var serverAddressFeature = app.ServerFeatures.Get();
if (serverAddressFeature != null)
{
app.UseMiddleware(serverAddressFeature);
}
else
{
app.UseMiddleware();
}
return app;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionMiddleware.cs
================================================
// 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.Hosting.Server.Features;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.HttpsPolicy.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.HttpsPolicy
{
public class HttpsRedirectionMiddleware
{
private readonly RequestDelegate _next;
private bool _portEvaluated = false;
private int? _httpsPort;
private readonly int _statusCode;
private readonly IServerAddressesFeature _serverAddressesFeature;
private readonly IConfiguration _config;
private readonly ILogger _logger;
///
/// Initializes the HttpsRedirectionMiddleware
///
///
///
///
///
public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config, ILoggerFactory loggerFactory)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_config = config ?? throw new ArgumentNullException(nameof(config));
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
var httpsRedirectionOptions = options.Value;
_httpsPort = httpsRedirectionOptions.HttpsPort;
_portEvaluated = _httpsPort.HasValue;
_statusCode = httpsRedirectionOptions.RedirectStatusCode;
_logger = loggerFactory.CreateLogger();
}
///
/// Initializes the HttpsRedirectionMiddleware
///
///
///
///
///
/// The
public HttpsRedirectionMiddleware(RequestDelegate next, IOptions options, IConfiguration config, ILoggerFactory loggerFactory,
IServerAddressesFeature serverAddressesFeature)
: this(next, options, config, loggerFactory)
{
_serverAddressesFeature = serverAddressesFeature ?? throw new ArgumentNullException(nameof(serverAddressesFeature));
}
///
/// Invokes the HttpsRedirectionMiddleware
///
///
///
public Task Invoke(HttpContext context)
{
if (context.Request.IsHttps || !TryGetHttpsPort(out var port))
{
return _next(context);
}
var host = context.Request.Host;
if (port != 443)
{
host = new HostString(host.Host, port);
}
else
{
host = new HostString(host.Host);
}
var request = context.Request;
var redirectUrl = UriHelper.BuildAbsolute(
"https",
host,
request.PathBase,
request.Path,
request.QueryString);
context.Response.StatusCode = _statusCode;
context.Response.Headers[HeaderNames.Location] = redirectUrl;
_logger.RedirectingToHttps(redirectUrl);
return Task.CompletedTask;
}
private bool TryGetHttpsPort(out int port)
{
// The IServerAddressesFeature will not be ready until the middleware is Invoked,
// Order for finding the HTTPS port:
// 1. Set in the HttpsRedirectionOptions
// 2. HTTPS_PORT environment variable
// 3. IServerAddressesFeature
// 4. Fail if not set
port = -1;
if (_portEvaluated)
{
port = _httpsPort ?? port;
return _httpsPort.HasValue;
}
_portEvaluated = true;
_httpsPort = _config.GetValue("HTTPS_PORT");
if (_httpsPort.HasValue)
{
port = _httpsPort.Value;
_logger.PortLoadedFromConfig(port);
return true;
}
if (_serverAddressesFeature == null)
{
_logger.FailedToDeterminePort();
return false;
}
int? httpsPort = null;
foreach (var address in _serverAddressesFeature.Addresses)
{
var bindingAddress = BindingAddress.Parse(address);
if (bindingAddress.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase))
{
// If we find multiple different https ports specified, throw
if (httpsPort.HasValue && httpsPort != bindingAddress.Port)
{
_logger.FailedMultiplePorts();
return false;
}
else
{
httpsPort = bindingAddress.Port;
}
}
}
if (httpsPort.HasValue)
{
_httpsPort = httpsPort;
port = _httpsPort.Value;
_logger.PortFromServer(port);
return true;
}
_logger.FailedToDeterminePort();
return false;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionOptions.cs
================================================
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.HttpsPolicy
{
///
/// Options for the HttpsRedirection middleware
///
public class HttpsRedirectionOptions
{
///
/// The status code used for the redirect response. The default is 307.
///
public int RedirectStatusCode { get; set; } = StatusCodes.Status307TemporaryRedirect;
///
/// The HTTPS port to be added to the redirected URL.
///
///
/// If the HttpsPort is not set, we will try to get the HttpsPort from the following:
/// 1. HTTPS_PORT environment variable
/// 2. IServerAddressesFeature
/// If that fails then the middleware will log a warning and turn off.
///
public int? HttpsPort { get; set; }
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/HttpsRedirectionServicesExtensions.cs
================================================
// 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.HttpsPolicy;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Builder
{
///
/// Extension methods for the HttpsRedirection middleware.
///
public static class HttpsRedirectionServicesExtensions
{
///
/// Adds HTTPS redirection services.
///
/// The for adding services.
/// A delegate to configure the .
///
public static IServiceCollection AddHttpsRedirection(this IServiceCollection services, Action configureOptions)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (configureOptions == null)
{
throw new ArgumentNullException(nameof(configureOptions));
}
services.Configure(configureOptions);
return services;
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/Microsoft.AspNetCore.HttpsPolicy.csproj
================================================
ASP.NET Core basic middleware for supporting HTTPS Redirection and HTTP Strict-Transport-Security.
netstandard2.0$(NoWarn);CS1591trueaspnetcore;https;hsts
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/baseline.netcore.json
================================================
{
"AssemblyIdentity": "Microsoft.AspNetCore.HttpsPolicy, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60",
"Types": [
{
"Name": "Microsoft.AspNetCore.HttpsPolicy.HstsMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpsPolicy.HstsOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_MaxAge",
"Parameters": [],
"ReturnType": "System.TimeSpan",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_MaxAge",
"Parameters": [
{
"Name": "value",
"Type": "System.TimeSpan"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_IncludeSubDomains",
"Parameters": [],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_IncludeSubDomains",
"Parameters": [
{
"Name": "value",
"Type": "System.Boolean"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_Preload",
"Parameters": [],
"ReturnType": "System.Boolean",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_Preload",
"Parameters": [
{
"Name": "value",
"Type": "System.Boolean"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_ExcludedHosts",
"Parameters": [],
"ReturnType": "System.Collections.Generic.IList",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "Invoke",
"Parameters": [
{
"Name": "context",
"Type": "Microsoft.AspNetCore.Http.HttpContext"
}
],
"ReturnType": "System.Threading.Tasks.Task",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
},
{
"Name": "config",
"Type": "Microsoft.Extensions.Configuration.IConfiguration"
},
{
"Name": "loggerFactory",
"Type": "Microsoft.Extensions.Logging.ILoggerFactory"
}
],
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [
{
"Name": "next",
"Type": "Microsoft.AspNetCore.Http.RequestDelegate"
},
{
"Name": "options",
"Type": "Microsoft.Extensions.Options.IOptions"
},
{
"Name": "config",
"Type": "Microsoft.Extensions.Configuration.IConfiguration"
},
{
"Name": "loggerFactory",
"Type": "Microsoft.Extensions.Logging.ILoggerFactory"
},
{
"Name": "serverAddressesFeature",
"Type": "Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature"
}
],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionOptions",
"Visibility": "Public",
"Kind": "Class",
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "get_RedirectStatusCode",
"Parameters": [],
"ReturnType": "System.Int32",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_RedirectStatusCode",
"Parameters": [
{
"Name": "value",
"Type": "System.Int32"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "get_HttpsPort",
"Parameters": [],
"ReturnType": "System.Nullable",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Method",
"Name": "set_HttpsPort",
"Parameters": [
{
"Name": "value",
"Type": "System.Nullable"
}
],
"ReturnType": "System.Void",
"Visibility": "Public",
"GenericParameter": []
},
{
"Kind": "Constructor",
"Name": ".ctor",
"Parameters": [],
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HstsBuilderExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseHsts",
"Parameters": [
{
"Name": "app",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HstsServicesExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "AddHsts",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
},
{
"Name": "configureOptions",
"Type": "System.Action"
}
],
"ReturnType": "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HttpsPolicyBuilderExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "UseHttpsRedirection",
"Parameters": [
{
"Name": "app",
"Type": "Microsoft.AspNetCore.Builder.IApplicationBuilder"
}
],
"ReturnType": "Microsoft.AspNetCore.Builder.IApplicationBuilder",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
},
{
"Name": "Microsoft.AspNetCore.Builder.HttpsRedirectionServicesExtensions",
"Visibility": "Public",
"Kind": "Class",
"Abstract": true,
"Static": true,
"Sealed": true,
"ImplementedInterfaces": [],
"Members": [
{
"Kind": "Method",
"Name": "AddHttpsRedirection",
"Parameters": [
{
"Name": "services",
"Type": "Microsoft.Extensions.DependencyInjection.IServiceCollection"
},
{
"Name": "configureOptions",
"Type": "System.Action"
}
],
"ReturnType": "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"Static": true,
"Extension": true,
"Visibility": "Public",
"GenericParameter": []
}
],
"GenericParameters": []
}
]
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/internal/HstsLoggingExtensions.cs
================================================
// 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.HttpsPolicy.Internal
{
internal static class HstsLoggingExtensions
{
private static readonly Action _notSecure;
private static readonly Action _excludedHost;
private static readonly Action _addingHstsHeader;
static HstsLoggingExtensions()
{
_notSecure = LoggerMessage.Define(LogLevel.Debug, 1, "The request is insecure. Skipping HSTS header.");
_excludedHost = LoggerMessage.Define(LogLevel.Debug, 2, "The host '{host}' is excluded. Skipping HSTS header.");
_addingHstsHeader = LoggerMessage.Define(LogLevel.Trace, 3, "Adding HSTS header to response.");
}
public static void SkippingInsecure(this ILogger logger)
{
_notSecure(logger, null);
}
public static void SkippingExcludedHost(this ILogger logger, string host)
{
_excludedHost(logger, host, null);
}
public static void AddingHstsHeader(this ILogger logger)
{
_addingHstsHeader(logger, null);
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.HttpsPolicy/internal/HttpsLoggingExtensions.cs
================================================
// 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.HttpsPolicy.Internal
{
internal static class HttpsLoggingExtensions
{
private static readonly Action _redirectingToHttps;
private static readonly Action _portLoadedFromConfig;
private static readonly Action _failedToDeterminePort;
private static readonly Action _failedMultiplePorts;
private static readonly Action _portFromServer;
static HttpsLoggingExtensions()
{
_redirectingToHttps = LoggerMessage.Define(LogLevel.Debug, 1, "Redirecting to '{redirect}'.");
_portLoadedFromConfig = LoggerMessage.Define(LogLevel.Debug, 2, "Https port '{port}' loaded from configuration.");
_failedToDeterminePort = LoggerMessage.Define(LogLevel.Warning, 3, "Failed to determine the https port for redirect.");
_failedMultiplePorts = LoggerMessage.Define(LogLevel.Warning, 4,
"Cannot determine the https port from IServerAddressesFeature, multiple values were found. " +
"Please set the desired port explicitly on HttpsRedirectionOptions.HttpsPort.");
_portFromServer = LoggerMessage.Define(LogLevel.Debug, 5, "Https port '{httpsPort}' discovered from server endpoints.");
}
public static void RedirectingToHttps(this ILogger logger, string redirect)
{
_redirectingToHttps(logger, redirect, null);
}
public static void PortLoadedFromConfig(this ILogger logger, int port)
{
_portLoadedFromConfig(logger, port, null);
}
public static void FailedToDeterminePort(this ILogger logger)
{
_failedToDeterminePort(logger, null);
}
public static void FailedMultiplePorts(this ILogger logger)
{
_failedMultiplePorts(logger, null);
}
public static void PortFromServer(this ILogger logger, int port)
{
_portFromServer(logger, port, null);
}
}
}
================================================
FILE: src/Microsoft.AspNetCore.ResponseCompression/BodyWrapperStream.cs
================================================
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.ResponseCompression
{
///
/// Stream wrapper that create specific compression stream only if necessary.
///
internal class BodyWrapperStream : Stream, IHttpBufferingFeature, IHttpSendFileFeature
{
private readonly HttpContext _context;
private readonly Stream _bodyOriginalStream;
private readonly IResponseCompressionProvider _provider;
private readonly IHttpBufferingFeature _innerBufferFeature;
private readonly IHttpSendFileFeature _innerSendFileFeature;
private ICompressionProvider _compressionProvider = null;
private bool _compressionChecked = false;
private Stream _compressionStream = null;
private bool _providerCreated = false;
private bool _autoFlush = false;
internal BodyWrapperStream(HttpContext context, Stream bodyOriginalStream, IResponseCompressionProvider provider,
IHttpBufferingFeature innerBufferFeature, IHttpSendFileFeature innerSendFileFeature)
{
_context = context;
_bodyOriginalStream = bodyOriginalStream;
_provider = provider;
_innerBufferFeature = innerBufferFeature;
_innerSendFileFeature = innerSendFileFeature;
}
protected override void Dispose(bool disposing)
{
if (_compressionStream != null)
{
_compressionStream.Dispose();
_compressionStream = null;
}
}
public override bool CanRead => false;
public override bool CanSeek => false;
public override bool CanWrite => _bodyOriginalStream.CanWrite;
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public override void Flush()
{
if (!_compressionChecked)
{
OnWrite();
// Flush the original stream to send the headers. Flushing the compression stream won't
// flush the original stream if no data has been written yet.
_bodyOriginalStream.Flush();
return;
}
if (_compressionStream != null)
{
_compressionStream.Flush();
}
else
{
_bodyOriginalStream.Flush();
}
}
public override Task FlushAsync(CancellationToken cancellationToken)
{
if (!_compressionChecked)
{
OnWrite();
// Flush the original stream to send the headers. Flushing the compression stream won't
// flush the original stream if no data has been written yet.
return _bodyOriginalStream.FlushAsync(cancellationToken);
}
if (_compressionStream != null)
{
return _compressionStream.FlushAsync(cancellationToken);
}
return _bodyOriginalStream.FlushAsync(cancellationToken);
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
OnWrite();
if (_compressionStream != null)
{
_compressionStream.Write(buffer, offset, count);
if (_autoFlush)
{
_compressionStream.Flush();
}
}
else
{
_bodyOriginalStream.Write(buffer, offset, count);
}
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
var tcs = new TaskCompletionSource