diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 551a39c48d..2583e4cf86 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -14,13 +14,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - name: Use Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v6 with: - node-version: 16.x + node-version: 'lts/*' - name: Run Markdownlint run: | echo "::add-matcher::.github/workflows/markdownlint-problem-matcher.json" npm i -g markdownlint-cli - markdownlint "**.md" + markdownlint "**/*.md" diff --git a/docs/DailyBuilds.md b/docs/DailyBuilds.md index 5ae0ee211d..752711e321 100644 --- a/docs/DailyBuilds.md +++ b/docs/DailyBuilds.md @@ -28,9 +28,10 @@ Then follow the [Getting Started](https://learn.microsoft.com/aspnet/core/fundam Some features, such as new target frameworks, may require prerelease tooling builds for Visual Studio. These are available in the [Visual Studio Preview](https://www.visualstudio.com/vs/preview/). -#### To debug daily builds using Visual Studio +To debug daily builds using Visual Studio +------------------------------------------ -* *Enable Source Link support* in Visual Studio should be enabled. -* *Enable source server support* in Visual should be enabled. -* *Enable Just My Code* should be disabled -* Under Symbols enable the *Microsoft Symbol Servers* setting. +- *Enable Source Link support* in Visual Studio should be enabled. +- *Enable source server support* in Visual should be enabled. +- *Enable Just My Code* should be disabled +- Under Symbols enable the *Microsoft Symbol Servers* setting. diff --git a/docs/designs/config.md b/docs/designs/config.md index 33090535fc..28a7c515fe 100644 --- a/docs/designs/config.md +++ b/docs/designs/config.md @@ -28,7 +28,7 @@ Proposals: ## Route config: The proxy has a [config mechanism](https://github.com/dotnet/yarp/blob/b2cf5bdddf7962a720672a75f2e93913d16dfee7/samples/IslandGateway.Sample/appsettings.json#L26-L32) to define routes and map those to back end groups. -``` +```json "Routes": [ { "RouteId": "backend1/route1", @@ -44,7 +44,7 @@ This basic structure is useful though the "Rule" [system](https://github.com/dot The ProxyRoute.Metadata dictionary may be able to be replaced or supplemented by giving direct access to the config node for that route. Compare to Kestrel's [EndpointConfig.ConfigSection](https://github.com/dotnet/aspnetcore/blob/f4d81e3af2b969744a57d76d4d622036ac514a6a/src/Servers/Kestrel/Core/src/Internal/ConfigurationReader.cs#L168-L175) property. That would allow for augmenting an endpoint with additional complex custom entries that the app code can reference for additional config actions. Update: The custom rule system was modified by [#24](https://github.com/dotnet/yarp/pull/24) so that the config now looks like this: -``` +```json "Routes": [ { "RouteId": "backend1/route1", @@ -69,7 +69,7 @@ A Backend is a collection of one or more BackendEndpoints and a set of policies Question: Why are the backends and the endpoints listed separately in config rather than nested? Object model links endpoints 1:1 with backends, so there doesn't seem to be a reason to list them separately. Existing: -``` +```json "Backends": [ { "BackendId": "backend1" @@ -94,7 +94,7 @@ Existing: }, ``` Nested: -``` +```json "Backends": [ { "BackendId": "backend1", @@ -117,7 +117,7 @@ Nested: ], ``` Additional feedback: Why is it using arrays instead of objects? These items are not order sensitive, and they already have id properties anyways. -``` +```json "Backends": { "backend1" : { "Endpoints": [ @@ -137,7 +137,7 @@ Additional feedback: Why is it using arrays instead of objects? These items are ``` Update: The backend and endpoint layout has been modified to the following: -``` +```json "Backends": { "backend1": { @@ -161,7 +161,7 @@ Update: The backend and endpoint layout has been modified to the following: Config reloading is not yet a blocking requirement but we do expect to need it in the future. This design needs to factor in how reloading might work when it does get added. -** NOTE ** The proxy code has a concept of Signals that is used to convey config change. We need to see how this integrates with change notifications from our config sources and flows through the system. +**NOTE** The proxy code has a concept of Signals that is used to convey config change. We need to see how this integrates with change notifications from our config sources and flows through the system. The Extensions config and options systems have support for change detection and reloading but very few components take advantage of it. Logging is the primary consumer today. @@ -188,7 +188,7 @@ The config reload code has been moved from the sample into the product assemblie ## Augmenting config via code Some things are easier to do in code and we want to be able to support that while still pulling more transient data from config. [Kestrel](https://github.com/dotnet/aspnetcore/blob/aff01ebd7f82d641a4cfbd4a34954300311d9c2b/src/Servers/Kestrel/samples/SampleApp/Startup.cs#L138-L147) has a model where endpoints are named in config and then can be reference by name in code for additional configuration. -``` +```json { "Kestrel": { "Endpoints": { @@ -200,7 +200,7 @@ Some things are easier to do in code and we want to be able to support that whil } } ``` -``` +```csharp options.Endpoint("NamedEndpoint", opt => { diff --git a/docs/designs/route-extensibility.md b/docs/designs/route-extensibility.md index b9691da63b..f3a9d55e6b 100644 --- a/docs/designs/route-extensibility.md +++ b/docs/designs/route-extensibility.md @@ -102,16 +102,16 @@ static IReverseProxyBuilder AddRouteExtension(this IReverseProxyBuilder builder, * The IConfigurationSection for the extension * The route object that is being extended * The existing extension instance in the case of configuration updates - - > When the configuration is parsed, the factory is called based on the configuration key name, and the resultant object is added to the route/cluster objects. - - > Regular YARP config will do a diff merge to handle config changes, and create new objects if applicable. The same mechanism needs to be used for extensions. If the configuration is updated, and an existing instance of the extension exists, then it will be passed to the factory. The factory can compare the current instance and re-use it, or copy its data across to a new instance based on the changes. Instances must stable, so existing instances shouldn't be modified if it would affect existing in-flight requests. YARP can't really enforce rules on how the objects are changed as we want the types to be user defined. +> +> When the configuration is parsed, the factory is called based on the configuration key name, and the resultant object is added to the route/cluster objects. +> +> Regular YARP config will do a diff merge to handle config changes, and create new objects if applicable. The same mechanism needs to be used for extensions. If the configuration is updated, and an existing instance of the extension exists, then it will be passed to the factory. The factory can compare the current instance and re-use it, or copy its data across to a new instance based on the changes. Instances must stable, so existing instances shouldn't be modified if it would affect existing in-flight requests. YARP can't really enforce rules on how the objects are changed as we want the types to be user defined. * When using a custom config provider, the Extensions collection can be populated by the custom provider directly, or the provider can expose an `IConfigurationSection` implementation and use the factory as described below. * When YARP is integrated with 3rd party config systems, such as K8s or ServiceFabric, those systems typically have a way of expressing custom properties, some of which will be used by YARP for the definition of routes/ clusters etc. To facilitate the ability for route and cluster extensions to be expressed within those systems, the integration provider should expose an `IConfigurationSection` implementation that maps between the integrated persistence format and YARP. `IConfigurationSection` is essentially a name/value lookup API, it should map pretty reasonably to the YAML or JSON formats used by the configuration systems, and not be an undue burden to implement on these integrations. -* Integration with 3rd party config systems can involve a remote process that YARP can pull its configuration from. I am [proposing another feature](#1710), that we formalize this pattern and have the ability to create a central YARP config provider, to which multiple YARP proxies can bind. This enables scalability in terms of being able to push config to multiple instances of YARP at once. +* Integration with 3rd party config systems can involve a remote process that YARP can pull its configuration from. I am [proposing another feature](https://github.com/dotnet/yarp/issues/1710), that we formalize this pattern and have the ability to create a central YARP config provider, to which multiple YARP proxies can bind. This enables scalability in terms of being able to push config to multiple instances of YARP at once. * To support this scenario, we should serialize the IConfiguration data and pass that across to the proxy instances. diff --git a/docs/designs/yarp-tunneling.md b/docs/designs/yarp-tunneling.md index 43472b4b31..8904ab1164 100644 --- a/docs/designs/yarp-tunneling.md +++ b/docs/designs/yarp-tunneling.md @@ -26,7 +26,7 @@ If the tunnel connection is broken, the back-end will attempt to reconnect to th - If the connection is refused with a 400 series error then further connections for that tunnel will not be made. > Issue: Do we need an API for the tunnel? As its created from code on the back-end, the app could have additional logic for control over the duration. Does it have API for status, clean shutdown, etc. - +> > Issue: Will additional connections be created for scalability - H2 perf becomes limited after 100 simultaneous requests. How does the front-end know to pair a second back-end connection? The Front End should keep the WSS connection alive by sending pings every 30s if there is no other traffic. This should be done at the WSS layer. @@ -198,9 +198,9 @@ Samples should be created that show best practices using a secure mechanism such The purpose of the tunnel is to simplify service exposure by creating a tunnel through the firewall that enables external requests to be made to destination servers on the back-end network. There are a number of mitigations that reduces the risk of this feature: -* No endpoints are exposed via the firewall - it does not expose any new endpoints that could act as attack vectors. The tunnel is an outbound connection made between the back-end and the front-end. -* Traffic directed via the tunnel will need to have corresponding routes in the Back End configuration. Traffic will only be routed if there is a respective route and cluster configuration. Tunnel traffic can't specify arbitrary URLs that would be directed to a hostname not included in the back-end route table configuration. -* Tunnel connections should only be over HTTPs +- No endpoints are exposed via the firewall - it does not expose any new endpoints that could act as attack vectors. The tunnel is an outbound connection made between the back-end and the front-end. +- Traffic directed via the tunnel will need to have corresponding routes in the Back End configuration. Traffic will only be routed if there is a respective route and cluster configuration. Tunnel traffic can't specify arbitrary URLs that would be directed to a hostname not included in the back-end route table configuration. +- Tunnel connections should only be over HTTPs ## Metrics @@ -210,10 +210,8 @@ The purpose of the tunnel is to simplify service exposure by creating a tunnel t | Condition | Description | | --- | --- | -| No tunnel has connected | If the front end receives a request for a route that is backed by a tunnel and no tunnels have been created, then it should respond to those requests with a 502 "Bad Gateway" error| +| No tunnel has connected | If the front end receives a request for a route that is backed by a tunnel and no tunnels have been created, then it should respond to those requests with a 502 "Bad Gateway" error | ## Web Transport Web Transport is an interesting future protocol choice for the tunnel. - - diff --git a/docs/operations/BackportingToPreview.md b/docs/operations/BackportingToPreview.md index c5448ddde9..f9a5fa51cb 100644 --- a/docs/operations/BackportingToPreview.md +++ b/docs/operations/BackportingToPreview.md @@ -19,7 +19,7 @@ Backporting changes is very similar to a regular release. Changes are made on th - `git push upstream --tags` - Create a new [release](https://github.com/dotnet/yarp/releases). -# Internal fixes +## Internal fixes Issues with significant security or disclosure concerns need to be fixed privately first. All of this work will happen on the internal Azdo repo and be merged to the public github repo at the time of disclosure. diff --git a/docs/operations/Branching.md b/docs/operations/Branching.md index f410cb4d59..bfc636f875 100644 --- a/docs/operations/Branching.md +++ b/docs/operations/Branching.md @@ -18,6 +18,6 @@ Update branding in `main`: Update the runtimes and SDKs in `global.json` in `main`: -Check that the global.json includes the latest 8.0 runtime versions from [here](https://dotnet.microsoft.com/download/dotnet/8.0), and 9.0 from [here](https://dotnet.microsoft.com/download/dotnet/9.0). +Check that the global.json includes the latest 8.0 runtime versions from [the .NET 8.0 download page](https://dotnet.microsoft.com/download/dotnet/8.0), and 9.0 from [the .NET 9.0 download page](https://dotnet.microsoft.com/download/dotnet/9.0). [`eng/Versions.props`]: ../../eng/Versions.props \ No newline at end of file diff --git a/docs/operations/DependencyFlow.md b/docs/operations/DependencyFlow.md index 99df4daf79..dc55d996c9 100644 --- a/docs/operations/DependencyFlow.md +++ b/docs/operations/DependencyFlow.md @@ -51,7 +51,7 @@ https://github.com/dotnet/arcade (.NET Eng - Latest) ==> 'https://github.com/dot To add a new subscription, run `darc add-subscription` with no arguments. An editor window will open with a TODO script like this: -``` +```yaml Channel: Source Repository URL: Target Repository URL: @@ -63,7 +63,7 @@ Merge Policies: [] A number of comments will also be present, describing available values and what they do. Fill these fields in, for example: -``` +```yaml Channel: .NET Eng - Latest Source Repository URL: https://github.com/dotnet/arcade Target Repository URL: https://github.com/dotnet/yarp @@ -97,7 +97,7 @@ Set up dependency flow for the new branch: * `Target Branch` = `release/X` (where `X` is the YARP release version) * `Update Frequency` = `EveryWeek` * `Merge Policies` is a multiline value, it should look like this: - ``` + ```yaml Merge Policies: - Name: Standard Properties: {} diff --git a/docs/operations/Release.md b/docs/operations/Release.md index 5f501c22e5..db0b2afdeb 100644 --- a/docs/operations/Release.md +++ b/docs/operations/Release.md @@ -71,7 +71,7 @@ Enter a comment such as "release for preview X" approve finalize the release. The packages will be pushed and when the "NuGet.org" stage turns green, the packages are published! -*Note: NuGet publishing is quick, but there is a background indexing process that can mean it will take up to several hours for packages to become available* +**Note:** NuGet publishing is quick, but there is a background indexing process that can mean it will take up to several hours for packages to become available ## Tag the commit @@ -121,6 +121,7 @@ There should only be one [preview branch on the repo](https://github.com/dotnet/ 11. [Offline] Wait for the archival completion report to arrive. Check that the size and number of archived files match the YARP repo. ### Recommended fields' values for archival request form + | Field | Value | | --- | --- | | Team Alias | dotnetrp | diff --git a/docs/roadmap.md b/docs/roadmap.md index 3eb4aa5db9..ebdf58ca2f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,22 +1,22 @@ # YARP Roadmap -### Supported YARP versions +## Supported YARP versions [Latest releases](https://github.com/dotnet/yarp/releases) | Version | Release Date | Latest Patch Version | End of Support | | -- | -- | -- | -- | -| [YARP 2.3](https://github.com/dotnet/yarp/releases/tag/v2.3.0) | February 27, 2025 | [2.3.0](https://github.com/dotnet/yarp/releases/tag/v2.3.0) | | +| [YARP 2.3](https://github.com/dotnet/yarp/releases/tag/v2.3.0) | February 27, 2025 | [2.3.0](https://github.com/dotnet/yarp/releases/tag/v2.3.0) | | ### End-of-life YARP versions | Version | Released date | Final Patch Version | End of support | | -- | -- | -- | -- | -| [YARP 2.2](https://github.com/dotnet/yarp/releases/tag/v2.2.0) | September 3, 2024 | [2.2.0](https://github.com/dotnet/yarp/releases/tag/v2.2.0) | August 27, 2025 | -| [YARP 2.1](https://github.com/dotnet/yarp/releases/tag/v2.1.0) | November 17, 2023 | [2.1.0](https://github.com/dotnet/yarp/releases/tag/v2.1.0) | March 3, 2025 | -| [YARP 2.0](https://github.com/dotnet/yarp/releases/tag/v2.0.0) | February 14, 2023 | [2.0.1](https://github.com/dotnet/yarp/releases/tag/v2.0.1) | May 17, 2024 | -| [YARP 1.1](https://github.com/dotnet/yarp/releases/tag/v1.1.0) | May 2, 2022 | [1.1.2](https://github.com/dotnet/yarp/releases/tag/v1.1.2) | August 14, 2023 | -| [YARP 1.0](https://github.com/dotnet/yarp/releases/tag/v1.0.0) | November 9, 2021 | [1.0.1](https://github.com/dotnet/yarp/releases/tag/v1.0.1) | November 2, 2022 | +| [YARP 2.2](https://github.com/dotnet/yarp/releases/tag/v2.2.0) | September 3, 2024 | [2.2.0](https://github.com/dotnet/yarp/releases/tag/v2.2.0) | August 27, 2025 | +| [YARP 2.1](https://github.com/dotnet/yarp/releases/tag/v2.1.0) | November 17, 2023 | [2.1.0](https://github.com/dotnet/yarp/releases/tag/v2.1.0) | March 3, 2025 | +| [YARP 2.0](https://github.com/dotnet/yarp/releases/tag/v2.0.0) | February 14, 2023 | [2.0.1](https://github.com/dotnet/yarp/releases/tag/v2.0.1) | May 17, 2024 | +| [YARP 1.1](https://github.com/dotnet/yarp/releases/tag/v1.1.0) | May 2, 2022 | [1.1.2](https://github.com/dotnet/yarp/releases/tag/v1.1.2) | August 14, 2023 | +| [YARP 1.0](https://github.com/dotnet/yarp/releases/tag/v1.0.0) | November 9, 2021 | [1.0.1](https://github.com/dotnet/yarp/releases/tag/v1.0.1) | November 2, 2022 | ## Support @@ -24,10 +24,10 @@ YARP support is provided by the product team - the engineers working on YARP - w The support period for YARP releases is as follows: -| Release | Issue Type | Support period | -| --- | ---| --- | -| Major or minor version | Security Bugs, Major behavior defects | Until next GA + 6 Months | -| Patch version | Minor behavior defects | Until next GA | +| Release | Issue Type | Support period | +| --- | --- | --- | +| Major or minor version | Security Bugs, Major behavior defects | Until next GA + 6 Months | +| Patch version | Minor behavior defects | Until next GA | | Preview | Security Bugs, Major behavior defects | Until next preview | | | All other | None - may be addressed by next preview | diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 618aa4bfaf..92b2b22023 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -3,17 +3,17 @@ - + https://github.com/dotnet/arcade - 65e09c040143048211dcf6b2bd69336cbf27eec6 + 367e3ab44812021f59aaf4c7506d5b4569769eec - + https://github.com/dotnet/arcade - 65e09c040143048211dcf6b2bd69336cbf27eec6 + 367e3ab44812021f59aaf4c7506d5b4569769eec - + https://github.com/dotnet/arcade - 65e09c040143048211dcf6b2bd69336cbf27eec6 + 367e3ab44812021f59aaf4c7506d5b4569769eec diff --git a/eng/Versions.props b/eng/Versions.props index 05aa93bab8..97fdad2c59 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -15,7 +15,7 @@ 8.0.0 6.0.36 0.2.0-alpha.24576.2 - 11.0.0-beta.25605.2 + 11.0.0-beta.26059.1 6.0.0 4.18.4 4.9.4 diff --git a/eng/common/core-templates/steps/install-microbuild-impl.yml b/eng/common/core-templates/steps/install-microbuild-impl.yml index b9e0143ee9..da22beb3f6 100644 --- a/eng/common/core-templates/steps/install-microbuild-impl.yml +++ b/eng/common/core-templates/steps/install-microbuild-impl.yml @@ -18,7 +18,7 @@ parameters: type: boolean steps: -- ${{ if eq(parameters.enablePreviewMicrobuild, 'true') }}: +- ${{ if eq(parameters.enablePreviewMicrobuild, true) }}: - task: MicroBuildSigningPluginPreview@4 displayName: Install Preview MicroBuild plugin inputs: ${{ parameters.microbuildTaskInputs }} diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml index ac019e2d03..3ad83b8c30 100644 --- a/eng/common/core-templates/steps/source-index-stage1-publish.yml +++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml @@ -14,8 +14,8 @@ steps: workingDirectory: $(Agent.TempDirectory) - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.sourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.sourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools displayName: "Source Index: Download netsourceindex Tools" # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. workingDirectory: $(Agent.TempDirectory) diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 8abfb71f72..9b7eede4e5 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -72,7 +72,7 @@ __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" -__FreeBSDBase="13.4-RELEASE" +__FreeBSDBase="13.5-RELEASE" __FreeBSDPkg="1.21.3" __FreeBSDABI="13" __FreeBSDPackages="libunwind" @@ -383,7 +383,7 @@ while :; do ;; freebsd14) __CodeName=freebsd - __FreeBSDBase="14.2-RELEASE" + __FreeBSDBase="14.3-RELEASE" __FreeBSDABI="14" __SkipUnmount=1 ;; diff --git a/eng/common/internal-feed-operations.ps1 b/eng/common/internal-feed-operations.ps1 index 92b77347d9..c282d3ae40 100644 --- a/eng/common/internal-feed-operations.ps1 +++ b/eng/common/internal-feed-operations.ps1 @@ -26,7 +26,7 @@ function SetupCredProvider { $url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1' Write-Host "Writing the contents of 'installcredprovider.ps1' locally..." - Invoke-WebRequest $url -OutFile installcredprovider.ps1 + Invoke-WebRequest $url -UseBasicParsing -OutFile installcredprovider.ps1 Write-Host 'Installing plugin...' .\installcredprovider.ps1 -Force diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh index 64b87d0bcc..11f81cbd40 100644 --- a/eng/common/native/install-dependencies.sh +++ b/eng/common/native/install-dependencies.sh @@ -27,7 +27,7 @@ case "$os" in libssl-dev libkrb5-dev pigz cpio localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 - elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos"]; then + elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos" ]; then pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)" $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio elif [ "$ID" = "amzn" ]; then diff --git a/eng/common/post-build/nuget-verification.ps1 b/eng/common/post-build/nuget-verification.ps1 index ac5c69ffca..eea88e653c 100644 --- a/eng/common/post-build/nuget-verification.ps1 +++ b/eng/common/post-build/nuget-verification.ps1 @@ -65,7 +65,7 @@ if ($NuGetExePath) { Write-Host "Downloading nuget.exe from $nugetExeUrl..." $ProgressPreference = 'SilentlyContinue' try { - Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe + Invoke-WebRequest $nugetExeUrl -UseBasicParsing -OutFile $downloadedNuGetExe $ProgressPreference = 'Continue' } catch { $ProgressPreference = 'Continue' diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index 4bf4cf41bd..49284d1097 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -12,7 +12,7 @@ Basic guidance is: See [azure-pipelines.yml](../../azure-pipelines.yml) (templates-official example) or [azure-pipelines-pr.yml](../../azure-pipelines-pr.yml) (templates example) for examples. -#### The `templateIs1ESManaged` parameter +### The `templateIs1ESManaged` parameter The `templateIs1ESManaged` is available on most templates and affects which of the variants is used for nested templates. See [Development Notes](#development-notes) below for more information on the `templateIs1ESManaged1 parameter. @@ -59,7 +59,7 @@ Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable whe ## Development notes -**Folder / file structure** +### Folder / file structure ``` text eng\common\ diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 1556562c68..f6bde26837 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -273,7 +273,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) { Retry({ Write-Host "GET $uri" - Invoke-WebRequest $uri -OutFile $installScript + Invoke-WebRequest $uri -UseBasicParsing -OutFile $installScript }) } @@ -506,7 +506,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) { Write-Host "Downloading $packageName $packageVersion" $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit Retry({ - Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath + Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -UseBasicParsing -OutFile $packagePath }) if (!(Test-Path $packagePath)) { @@ -552,23 +552,30 @@ function LocateVisualStudio([object]$vsRequirements = $null){ Write-Host "Downloading vswhere $vswhereVersion" $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit Retry({ - Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe + Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -UseBasicParsing -OutFile $vswhereExe }) } - if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs } + if (!$vsRequirements) { + if (Get-Member -InputObject $GlobalJson.tools -Name 'vs' -ErrorAction SilentlyContinue) { + $vsRequirements = $GlobalJson.tools.vs + } else { + $vsRequirements = $null + } + } + $args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*') if (!$excludePrereleaseVS) { $args += '-prerelease' } - if (Get-Member -InputObject $vsRequirements -Name 'version') { + if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'version' -ErrorAction SilentlyContinue)) { $args += '-version' $args += $vsRequirements.version } - if (Get-Member -InputObject $vsRequirements -Name 'components') { + if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'components' -ErrorAction SilentlyContinue)) { foreach ($component in $vsRequirements.components) { $args += '-requires' $args += $component diff --git a/global.json b/global.json index 9ae7951295..777a82285b 100644 --- a/global.json +++ b/global.json @@ -1,9 +1,9 @@ { "sdk": { - "version": "10.0.100" + "version": "11.0.100-alpha.1.25618.104" }, "tools": { - "dotnet": "10.0.100", + "dotnet": "11.0.100-alpha.1.25618.104", "runtimes": { "dotnet": [ "8.0.13", @@ -19,7 +19,7 @@ "runner": "Microsoft.Testing.Platform" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.25605.2", - "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.25605.2" + "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26059.1", + "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.26059.1" } } diff --git a/samples/BasicYarpSample/README.md b/samples/BasicYarpSample/README.md index 5dee4eefb4..ac380b1167 100644 --- a/samples/BasicYarpSample/README.md +++ b/samples/BasicYarpSample/README.md @@ -35,23 +35,22 @@ The proxy will listen to HTTP requests on port 5000, and HTTPS on port 5001. The ### Command line -* Download and install the .NET SDK (free) from https://dotnet.microsoft.com/download if not already installed. Versions are available for Windows, Linux and MacOS. -* Clone or extract a zip of the sample files. -* Use ```dotnet run``` either within the sample folder or passing in the path to the .csproj file to start the server. -* File change notification is used for the appsettings.json file so changes can be made on the fly. - +- Download and install the .NET SDK (free) from https://dotnet.microsoft.com/download if not already installed. Versions are available for Windows, Linux and MacOS. +- Clone or extract a zip of the sample files. +- Use ```dotnet run``` either within the sample folder or passing in the path to the .csproj file to start the server. +- File change notification is used for the appsettings.json file so changes can be made on the fly. ### Visual Studio Code -* Download and install Visual Studio Code (free) from https://code.visualstudio.com/ - versions are available for Windows, Linux and MacOS. -* Download and install the .NET SDK from https://dotnet.microsoft.com/download if not already installed. Versions are available for Windows, Linux and MacOS. -* Open the folder for the sample in VS Code (File->Open Folder). -* Press F5 to debug, or Ctrl + F5 to run the sample without debugging. +- Download and install Visual Studio Code (free) from https://code.visualstudio.com/ - versions are available for Windows, Linux and MacOS. +- Download and install the .NET SDK from https://dotnet.microsoft.com/download if not already installed. Versions are available for Windows, Linux and MacOS. +- Open the folder for the sample in VS Code (File->Open Folder). +- Press F5 to debug, or Ctrl + F5 to run the sample without debugging. ### Visual Studio -* Download and install Visual Studio from https://visualstudio.microsoft.com/ - versions are available for Windows and MacOS, including a free community edition. -* Open the project file. -* Press F5 to debug, or Ctrl + F5 to run the sample without debugging. +- Download and install Visual Studio from https://visualstudio.microsoft.com/ - versions are available for Windows and MacOS, including a free community edition. +- Open the project file. +- Press F5 to debug, or Ctrl + F5 to run the sample without debugging. ## Things to try - Change the ports the proxy listens on using the URLs property in configuration or on the command line. diff --git a/samples/KubernetesIngress.Sample/Combined/README.md b/samples/KubernetesIngress.Sample/Combined/README.md index 7b88a7c7fd..877c5d7f99 100644 --- a/samples/KubernetesIngress.Sample/Combined/README.md +++ b/samples/KubernetesIngress.Sample/Combined/README.md @@ -8,7 +8,7 @@ The sample ingress controller is a single deployable. From the base directory for this repo (where the .slnx file is), run the command: -``` +```bash docker build -t yarp-combined:latest -f ./samples/KubernetesIngress.Sample/Combined/Dockerfile . ``` diff --git a/samples/KubernetesIngress.Sample/Ingress/README.md b/samples/KubernetesIngress.Sample/Ingress/README.md index d7a3ded838..68aeaa26a8 100644 --- a/samples/KubernetesIngress.Sample/Ingress/README.md +++ b/samples/KubernetesIngress.Sample/Ingress/README.md @@ -12,7 +12,7 @@ NOTE: Yarp Kubernetes can also be configured as a combined (single) deployable. From the base directory for this repo (where the .slnx file is), run the commands: -``` +```bash docker build -t yarp-monitor:latest -f ./samples/KubernetesIngress.Sample/Monitor/Dockerfile . docker build -t yarp-ingress:latest -f ./samples/KubernetesIngress.Sample/Ingress/Dockerfile . ``` @@ -27,7 +27,7 @@ docker build -t yarp-ingress:latest -f ./samples/KubernetesIngress.Sample/Ingres 1. Run the command `kubectl apply -f ./samples/KubernetesIngress.Sample/Ingress/ingress.yaml` To undeploy the ingress, run the commands -``` +```bash kubectl delete -f ./samples/KubernetesIngress.Sample/Ingress/ingress.yaml kubectl delete -f ./samples/KubernetesIngress.Sample/Monitor/ingress-monitor.yaml ``` diff --git a/samples/KubernetesIngress.Sample/README.md b/samples/KubernetesIngress.Sample/README.md index 9654af6890..416505bcaa 100644 --- a/samples/KubernetesIngress.Sample/README.md +++ b/samples/KubernetesIngress.Sample/README.md @@ -34,7 +34,7 @@ The `Yarp.Kubernetes.Controller` project does not support: The `Yarp.Kubernetes.Controller` project supports a number of **optional** annotations on Ingress resources for functionality provided by YARP. These annotations would be specified like this: -``` +```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: @@ -97,13 +97,13 @@ The table below lists the available annotations. |yarp.ingress.kubernetes.io/http-client|[HttpClientConfig](https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.httpclientconfig)| |yarp.ingress.kubernetes.io/http-request|[ForwarderRequestConfig](https://learn.microsoft.com/en-us/dotnet/api/yarp.reverseproxy.forwarder.forwarderrequestconfig)| |yarp.ingress.kubernetes.io/load-balancing|string| -|yarp.ingress.kubernetes.io/route-metadata|Dictionary| +|yarp.ingress.kubernetes.io/route-metadata|Dictionary<string, string>| |yarp.ingress.kubernetes.io/session-affinity|[SessionAffinityConfig](https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.sessionaffinityconfig)| -|yarp.ingress.kubernetes.io/transforms|List>| -|yarp.ingress.kubernetes.io/route-headers|List<[RouteHeader](https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routeheader)>| -|yarp.ingress.kubernetes.io/route-queryparameters|List<[RouteQueryParameter](https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routequeryparameter)>| +|yarp.ingress.kubernetes.io/transforms|List<Dictionary<string, string>>| +|yarp.ingress.kubernetes.io/route-headers|List<[RouteHeader](https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routeheader)>| +|yarp.ingress.kubernetes.io/route-queryparameters|List<[RouteQueryParameter](https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routequeryparameter)>| |yarp.ingress.kubernetes.io/route-order|int| -|yarp.ingress.kubernetes.io/route-methods|List| +|yarp.ingress.kubernetes.io/route-methods|List<string>| #### Authorization Policy @@ -139,7 +139,7 @@ Proactively monitors destination health by sending periodic probing requests to See https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/dests-health-checks. -``` +```yaml yarp.ingress.kubernetes.io/health-check | Active: Enabled: true @@ -155,7 +155,7 @@ Configures the HTTP client that will be used for the destination service. See https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/http-client-config. -``` +```yaml yarp.ingress.kubernetes.io/http-client: | SslProtocols: Ssl3 MaxConnectionsPerServer: 2 @@ -168,7 +168,7 @@ Configures the HTTP request that will be sent to the destination service. See https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.forwarder.forwarderrequestconfig. -``` +```yaml yarp.ingress.kubernetes.io/http-request: | ActivityTimeout: '00:01:00' Version: '2.0' @@ -186,7 +186,7 @@ See https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/load-balan See https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routeconfig.metadata#yarp-reverseproxy-configuration-routeconfig-metadata. -``` +```yaml yarp.ingress.kubernetes.io/route-metadata: | Custom: "orange" Tenant: "12345" @@ -196,7 +196,7 @@ yarp.ingress.kubernetes.io/route-metadata: | See https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/session-affinity. -``` +```yaml yarp.ingress.kubernetes.io/session-affinity: | Enabled: true Policy: Cookie @@ -217,7 +217,7 @@ yarp.ingress.kubernetes.io/session-affinity: | Transforms use the YAML key-value pairs as per the YARP [Request Transforms](https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/transforms#request-transforms) -``` +```yaml yarp.ingress.kubernetes.io/transforms: | - PathPrefix: "/apis" - RequestHeader: header1 @@ -230,7 +230,7 @@ yarp.ingress.kubernetes.io/transforms: | See https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routeheader. -``` +```yaml yarp.ingress.kubernetes.io/route-headers: | - Name: the-header-key Values: @@ -250,7 +250,7 @@ yarp.ingress.kubernetes.io/route-headers: | See https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routequeryparameter. -``` +```yaml yarp.ingress.kubernetes.io/route-queryparameters: | - Name: the-queryparameter-name Values: @@ -268,7 +268,7 @@ yarp.ingress.kubernetes.io/route-queryparameters: | See https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routeconfig.order#yarp-reverseproxy-configuration-routeconfig-order. -``` +```yaml yarp.ingress.kubernetes.io/route-order: '10' ``` @@ -276,7 +276,7 @@ yarp.ingress.kubernetes.io/route-order: '10' See https://learn.microsoft.com/dotnet/api/yarp.reverseproxy.configuration.routematch.methods#yarp-reverseproxy-configuration-routematch-methods. -``` +```yaml yarp.ingress.kubernetes.io/route-methods: | - GET - POST diff --git a/samples/KubernetesIngress.Sample/backend/README.md b/samples/KubernetesIngress.Sample/backend/README.md index 95db52b373..a4a3f9fe05 100644 --- a/samples/KubernetesIngress.Sample/backend/README.md +++ b/samples/KubernetesIngress.Sample/backend/README.md @@ -6,7 +6,7 @@ This directory contains a sample ASP.NET Core application that acts as a "backen From the base directory for this repo (where the .slnx file is), run the commands: -``` +```bash docker build -t backend:latest -f ./samples/KubernetesIngress.Sample/backend/Dockerfile . ``` @@ -18,7 +18,7 @@ docker build -t backend:latest -f ./samples/KubernetesIngress.Sample/backend/Doc 1. Run the command `kubectl apply -f ./samples/KubernetesIngress.Sample/backend/ingress-sample.yaml` To undeploy the backend, run the commands -``` +```bash kubectl delete -f ./samples/KubernetesIngress.Sample/backend/ingress-sample.yaml kubectl delete -f ./samples/KubernetesIngress.Sample/backend/backend.yaml ``` diff --git a/samples/Prometheus/README.md b/samples/Prometheus/README.md index 2402d03578..1f72346267 100644 --- a/samples/Prometheus/README.md +++ b/samples/Prometheus/README.md @@ -44,8 +44,7 @@ The subsystems are: - **run10destinations** - Scripts for Windows & Linux that will start the sample server listening to endpoints http://localhost:10000 to http://localhost:10009 - **prometheus.yml** - - A sample config file for Prometheus that includes polling from http://localhost:5000/metrics for the results from the server. - + - A sample config file for Prometheus that includes polling from http://localhost:5000/metrics for the results from the server. ## Running the sample diff --git a/samples/README.md b/samples/README.md index e88bff433c..0414796147 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,6 +1,6 @@ # Samples -**Warning: Breaking Changes** +## Warning: Breaking Changes The samples in this folder are in sync with the main branch for YARP. If there have been breaking changes to the API or configuration, they may not match what is published on Nuget. To avoid disappointment, if using the samples with the YARP library published to Nuget, please change to the branch to match the latest release or preview, either using the branch dropdown or these links: @@ -13,17 +13,17 @@ The samples in this folder are in sync with the main branch for YARP. If there h The following samples are provided: | Name | Description | -|------- | ----- | +| ------- | ----- | | [Basic Yarp Sample](BasicYarpSample) | A simple sample that shows how to add YARP to the empty ASP.NET sample to create a fully functioning reverse proxy. | | [Configuration](ReverseProxy.Config.Sample) | Shows all the options that are available in the YARP config file | | [Minimal](ReverseProxy.Minimal.Sample) | Shows a minimal config-based YARP application using .NET 6's [Minimal Hosting for ASP.NET Core](https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#introducing-minimal-apis) | | [Http.sys Delegation](ReverseProxy.HttpSysDelegation.Sample) | Shows an example of using YARP to do Http.sys queue delegation in addition to proxying. | -| [Transforms](ReverseProxy.Transforms.Sample) | Shows how to transform headers as part of the proxy operation | +| [Transforms](ReverseProxy.Transforms.Sample) | Shows how to transform headers as part of the proxy operation | | [Code extensibility](ReverseProxy.Code.Sample) | Shows how you can extend YARP using a custom configuration provider, and a middleware component as part of the YARP pipeline | | [Authentication & Authorization](ReverseProxy.Auth.Sample) | Shows how to add authentication and authorization for routes to the proxy | -| [Configuration Filter](ReverseProxy.ConfigFilter.Sample) | Shows how to use extensibility to modify configuration as its loaded from the configuration file. This sample implements an indirection to enable config values to be pulled from environment variables which can be useful in a cloud environment. | +| [Configuration Filter](ReverseProxy.ConfigFilter.Sample) | Shows how to use extensibility to modify configuration as its loaded from the configuration file. This sample implements an indirection to enable config values to be pulled from environment variables which can be useful in a cloud environment. | | [Metrics](ReverseProxy.Metrics.Sample) | Shows how to consume YARP telemetry. This sample collects detailed timings for the sub-operations involved in the proxy process. | | [Using IHttpProxy Directly](ReverseProxy.Direct.Sample) | Shows how to use IHttpProxy, which performs the proxy operation, directly without using YARP's configuration, pipeline etc. | | [Lets Encrypt](ReverseProxy.LetsEncrypt.Sample) | Shows how to use a certificate authority such as Lets Encrypt to set up TLS termination in YARP. | -| [Kubernetes Ingress](KubernetesIngress.Sample) | Shows how to use YARP as a Kubernetes ingress controller | +| [Kubernetes Ingress](KubernetesIngress.Sample) | Shows how to use YARP as a Kubernetes ingress controller | | [Prometheus](Prometheus) | Shows how to consume the YARP telemetry library and export metrics to external telemetry such as Prometheus | diff --git a/samples/ReverseProxy.Auth.Sample/README.md b/samples/ReverseProxy.Auth.Sample/README.md index 5a957746f2..11997181ba 100644 --- a/samples/ReverseProxy.Auth.Sample/README.md +++ b/samples/ReverseProxy.Auth.Sample/README.md @@ -4,25 +4,24 @@ This sample shows how the YARP proxy can be integrated with the ASP.NET [authent The sample includes the following parts: -- ### [Program.cs](Program.cs) +- **[Program.cs](Program.cs)** Sets up the ASP.NET server to have the proxy together with the other middleware for authentication, authorization and Razor pages. It sets up a custom authorization policy "myPolicy" with a custom claim. -- ### [AccountController.cs](Controllers/AccountController.cs) +- **[AccountController.cs](Controllers/AccountController.cs)** Handles the login UI actions, and adds a value from a field in the login page to the "myCustomClaim" claim in the active identity. That claim is later required by the "myPolicy" authorization policy created in Startup.cs -- ### [appsettings.json](appsettings.json) +- **[appsettings.json](appsettings.json)** Defines the routes used by the reverse proxy including: - /default - requires authentication to access - /custom - uses the "myPolicy" authorization policy which requires authentication and a myCustomClaim value of "green" - /open - which uses "Anonymous" as the authorization policy so its always open regardless of the default - \* - which uses the built-in FallbackPolicy which is configured in Startup.cs to not require authentication -- ### Login UI +- **Login UI** The Razor pages in [Views/Account](Views/Account) provide the pages to login, logout and be shown when access is denied. ## Usage -Start the sample with ```dotnet run``` which by default will bind to http://localhost:5000 and https://localhost:5001. Try accessing the urls "/", "/default" and "/custom". - -When shown the login ui, pick a value for myCustomClaim. Using "green" will allow access to content under "/custom", using other values will deny access. +Start the sample with ```dotnet run``` which by default will bind to http://localhost:5000 and https://localhost:5001. Try accessing the urls "/", "/default" and "/custom". +When shown the login ui, pick a value for myCustomClaim. Using "green" will allow access to content under "/custom", using other values will deny access. \ No newline at end of file diff --git a/samples/ReverseProxy.Config.Sample/README.md b/samples/ReverseProxy.Config.Sample/README.md index 4a39239937..2de9e98664 100644 --- a/samples/ReverseProxy.Config.Sample/README.md +++ b/samples/ReverseProxy.Config.Sample/README.md @@ -26,7 +26,6 @@ The other files in the sample are the same as the getting started instructions. To make a request that would be successful against the second route, you will need a client request similar to: -``` +```bash curl -v -k -X GET -H "MyCustomHeader: value1" https://localhost:5001/download?MyQueryParameter=value1 -``` - +``` \ No newline at end of file diff --git a/samples/ReverseProxy.ConfigFilter.Sample/README.md b/samples/ReverseProxy.ConfigFilter.Sample/README.md index 2cd4e7c8fd..0e853930c0 100644 --- a/samples/ReverseProxy.ConfigFilter.Sample/README.md +++ b/samples/ReverseProxy.ConfigFilter.Sample/README.md @@ -8,8 +8,7 @@ The bulk of the code is the CustomConfigFilter class which implements the IProxy ## CustomConfigFilter Class -### ConfigureClusterAsync +### ConfigureClusterAsync This looks at the value of each destination and sees whether it matches the pattern {{env_var_name}}, and if so it treats it as an indirection to an environment variable, and replaces the destination address with the value of the named variable (if it exists). -**Note:** AppSettings.json includes a destination of {{contoso}} which will be matched. The Properties/launchSettings.json file includes a definition of the environment variable, which will be used by Visual Studio and other tools when debugging with "F5". - +**Note:** AppSettings.json includes a destination of {{contoso}} which will be matched. The Properties/launchSettings.json file includes a definition of the environment variable, which will be used by Visual Studio and other tools when debugging with "F5". \ No newline at end of file diff --git a/samples/ReverseProxy.Direct.Sample/README.md b/samples/ReverseProxy.Direct.Sample/README.md index 99ab2c7b1c..18e942bb25 100644 --- a/samples/ReverseProxy.Direct.Sample/README.md +++ b/samples/ReverseProxy.Direct.Sample/README.md @@ -1,13 +1,12 @@ # YARP Direct Proxy Example -Some customers who have an existing custom proxy for HTTP/1.1 are looking at YARP for a solution to handle more complex requests, such as HTTP/2, gRPC, WebSockets in future QUIC and HTTP/3. These applications have their own means of routing, load balancing, affinity, etc. and only need to forward a specific request to a specific destination. To make it easier to integrate YARP into these scenarios, the component that proxies requests is exposed via IHttpForwarder which can be called directly, and has few dependencies on the rest of YARP's infrastructure. +Some customers who have an existing custom proxy for HTTP/1.1 are looking at YARP for a solution to handle more complex requests, such as HTTP/2, gRPC, WebSockets in future QUIC and HTTP/3. These applications have their own means of routing, load balancing, affinity, etc. and only need to forward a specific request to a specific destination. To make it easier to integrate YARP into these scenarios, the component that proxies requests is exposed via IHttpForwarder which can be called directly, and has few dependencies on the rest of YARP's infrastructure. This example shows how to use IHttpForwarder to proxy a request to/from a specified destination. - The operation of the proxy can be thought of as: -``` +```text +-------------------+ +-------------------+ +-------------------+ | Client | ──(a)──► | Proxy | ──(b)──► | Destination | | | ◄──(d)── | | ◄──(c)── | | diff --git a/samples/ReverseProxy.HttpSysDelegation.Sample/README.md b/samples/ReverseProxy.HttpSysDelegation.Sample/README.md index 07d2963c21..f02beb4b56 100644 --- a/samples/ReverseProxy.HttpSysDelegation.Sample/README.md +++ b/samples/ReverseProxy.HttpSysDelegation.Sample/README.md @@ -1,7 +1,7 @@ # Http.sys Delegation Sample This sample shows how to use YARP to delegate requests to other Http.sys request queues instead of or in addition to proxying requests. Using Http.sys delegation requires hosting YARP on [ASP.NET Core's Http.sys server](https://docs.microsoft.com/aspnet/core/fundamentals/servers/httpsys) and requests can only be delegated to other processes which use Http.sys for request processing (e.g. ASP.NET Core using Http.sys server or IIS). -**Note: delegation only works for ASP.NET Core 6+ running on new versions of Windows** +**Note:** delegation only works for ASP.NET Core 6+ running on new versions of Windows ## Sample Projects There are two projects as part of this sample. A sample Http.sys server where traffic will be delegated to and a YARP example which both proxies and delegates request depending on the route. Both projects use the minimal API style but this isn't a requirement. diff --git a/samples/ReverseProxy.LetsEncrypt.Sample/README.md b/samples/ReverseProxy.LetsEncrypt.Sample/README.md index b4f450bd9d..10753480e4 100644 --- a/samples/ReverseProxy.LetsEncrypt.Sample/README.md +++ b/samples/ReverseProxy.LetsEncrypt.Sample/README.md @@ -4,10 +4,10 @@ The sample includes the following parts: -- ### [Program.cs](Program.cs) +- **[Program.cs](Program.cs)** It calls `IServiceCollection.AddLettuceEncrypt` in the `ConfigureServices` method. -- ### [appsettings.json](appsettings.json) +- **[appsettings.json](appsettings.json)** Sets up the required options for LettuceEncrypt including: - "DomainNames" - at least one domain name is required - "EmailAddress" - email address must be specified to register with the certificate authority diff --git a/samples/SampleServer/README.md b/samples/SampleServer/README.md index 86d550e6f5..62f96abfc3 100644 --- a/samples/SampleServer/README.md +++ b/samples/SampleServer/README.md @@ -4,20 +4,18 @@ This is a simple web server implementation that can be used to test YARP proxy, Functionality in this sample server includes: -### Echoing of Request Headers +## Echoing of Request Headers Provided that the request URI path doesn't match other endpoints described below, then the request headers will be reported back as text in the response body. This enables you to quickly see what headers were sent, for example to analyze header transforms made by the reverse proxy. - -### Healthcheck status endpoint +## Healthcheck status endpoint [HealthController](Controllers/HealthController.cs) implements an API endpoint for /api/health that will randomly return bad health status. -### WebSockets endpoint +## WebSockets endpoint [WebSocketsController](Controllers/WebSocketsController.cs) implements an endpoint for testing web sockets at /api/websockets. - ## Usage To run the sample server use: diff --git a/testassets/BenchmarkApp/README.md b/testassets/BenchmarkApp/README.md index 60807ebf78..f5dd56e5aa 100644 --- a/testassets/BenchmarkApp/README.md +++ b/testassets/BenchmarkApp/README.md @@ -4,7 +4,7 @@ 2. In one shell, run `crank-agent` 3. In another shell, run `crank` as follows: -``` +```bash crank ` --config https://raw.githubusercontent.com/aspnet/Benchmarks/master/scenarios/proxy.benchmarks.yml ` --scenario proxy-yarp `