Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
P

ProxyKit

> 编程语言
Open source

A toolkit to create code-first HTTP reverse proxies on ASP.NET Core

1.1K stars0 likes1 views
WebsiteGitHub

About

A toolkit to create code-first HTTP reverse proxies on ASP.NET Core

ProxyKit

[![NuGet][nuget badge]][nuget package] [![Feedz][feedz badge]][feedz package]

⚠️ ProxyKit is obsolescent. See announcement. Migrate to YARP.

A toolkit to create code-first HTTP Reverse Proxies hosted in ASP.NET Core as middleware. This allows focused code-first proxies that can be embedded in existing ASP.NET Core applications or deployed as a standalone server. Deployable anywhere ASP.NET Core is deployable such as Windows, Linux, Containers and Serverless (with caveats).

Having built proxies many times before, I felt it is time to make a package. Forked from [ASP.NET labs][aspnet labs], it has been heavily modified with a different API, to facilitate a wider variety of proxying scenarios (i.e. routing based on a JWT claim) and interception of the proxy requests / responses for customization of headers and (optionally) request / response bodies. It also uses [HttpClientFactory] internally that will mitigate against DNS caching issues making it suitable for microservice / container environments.

  • 1. Quick Start
    • 1.1. Install
    • 1.2. Forward HTTP Requests
    • 1.3. Forward WebSocket Requests
  • 2. Core Features
    • 2.1. Customising the upstream HTTP request
    • 2.2. Customising the upstream response
    • 2.3. X-Forwarded Headers
      • 2.3.1. Client Sent X-Forwarded-Headers
      • 2.3.2. Adding X-Forwarded-* Headers
      • 2.3.3. Copying X-Forwarded headers
    • 2.4. Configuring ProxyKit's HttpClient
    • 2.5. Error handling
    • 2.6. Testing
    • 2.7. Load Balancing
      • 2.7.1. Weighted Round Robin
    • 2.8. Typed Handlers
  • 3. Recipes
  • 4. Making upstream servers reverse proxy friendly
  • 5. Performance considerations
  • 6. Note about serverless
  • 7. Comparison with Ocelot
  • 8. How to build
  • 9. Contributing / Feedback / Questions
  • 10. Articles, blogs and other external links

1. Quick Start

1.1. Install

ProxyKit is a NetStandard2.0 package. Install into your ASP.NET Core project:

bash
dotnet add package ProxyKit

1.2. Forward HTTP Requests

In your Startup, add the proxy service:

csharp
public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddProxy();
    ...
}

Forward HTTP requests to upstream-server:5001:

csharp
public void Configure(IApplicationBuilder app)
{
    app.RunProxy(context => context
        .ForwardTo("http://upstream-server:5001/")
        .AddXForwardedHeaders()
        .Send());
}

What is happening here?

  1. context.ForwardTo(upstreamHost) is an extension method on HttpContext that creates and initializes an HttpRequestMessage with the original request headers copied over, yielding a ForwardContext.
  2. AddXForwardedHeaders adds X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto and X-Forwarded-PathBase headers to the upstream request.
  3. Send Sends the forward request to the upstream server and returns an HttpResponseMessage.
  4. The proxy middleware then takes the response and applies it to HttpContext.Response.

Note: RunProxy is [terminal] - anything added to the pipeline after RunProxy will never be executed.

1.3. Forward WebSocket Requests

Forward WebSocket requests to upstream-server:5002:

csharp
public void Configure(IApplicationBuilder app)
{
    app.UseWebSockets();
    app.UseWebSocketProxy(
        context => new Uri("ws://upstream-host:80/"),
        options => options.AddXForwardedHeaders());
}

What is happening here?

  1. app.UseWebSockets() must first be added otherwise websocket requests will never be handled by ProxyKit.
  2. The first parameter must return the URI of the upstream host with a scheme of ws://.
  3. The second parameter options allows you to do some customisation of the initial upstream requests such as adding some headers.

2. Core Features

2.1. Customising the upstream HTTP request

One can modify the upstream request headers prior to sending them to suit customisation needs. ProxyKit doesn't add, remove, nor modify any headers by default; one must opt in any behaviours explicitly.

In this example we will add a X-Correlation-ID header if the incoming request does not bear one:

csharp
public const string XCorrelationId = "X-Correlation-ID";

public void Configure(IApplicationBuilder app)
{
    app.RunProxy(context =>
    {
        var forwardContext = context.ForwardTo("http://upstream-server:5001/");
        if (!forwardContext.UpstreamRequest.Headers.Contains(XCorrelationId))
        {
            forwardContext.UpstreamRequest.Headers.Add(XCorrelationId, Guid.NewGuid().ToString());
        }
        return forwardContext.Send();
    });
}

This can be encapsulated as an extension method:

csharp
public static class CorrelationIdExtensions
{
    public const string XCorrelationId = "X-Correlation-ID";
    
    public static ForwardContext ApplyCorrelationId(this ForwardContext forwardContext)
    {
        if (!forwardContext.UpstreamRequest.Headers.Contains(XCorrelationId))
        {
            forwardContext.UpstreamRequest.Headers.Add(XCorrelationId, Guid.NewGuid().ToString());
        }
        return forwardContext;
    }
}

... making the proxy code a little nicer to read:

csharp
public void Configure(IApplicationBuilder app)
{
    app.RunProxy(context => context
        .ForwardTo("http://upstream-server:5001/")
        .ApplyCorrelationId()
        .Send());
}

2.2. Customising the upstream response

The response from an upstream server can be modified before it is sent to the client. In this example we are removing a header:

csharp
public void Configure(IApplicationBuilder app)
{
    app.RunProxy(async context =>
    {
        var response = await context
            .ForwardTo("http://localhost:5001/")
            .Send();

        response.Headers.Remove("MachineID");

        return response;
    });
}

2.3. X-Forwarded Headers

2.3.1. Client Sent X-Forwarded-Headers

:warning: To mitigate against spoofing attacks and misconfiguration ProxyKit does not copy X-Forward-* headers from the incoming request to the upstream request by default. Copying them requires opting in; see 2.3.3 Copying X-Forwarded headers below.

2.3.2. Adding X-Forwarded-* Headers

Many applications will need to know what their "outside" host / URL is in order to generate correct values. This is achieved using X-Forwarded-* and Forwarded headers. ProxyKit supports applying X-Forward-* headers out of the box (applying Forwarded headers support is on backlog). At the time of writing, Forwarded is not supported in ASP.NET Core.

To add X-Forwarded-* headers to the request to the upstream server:

csharp
public void Configure(IApplicationBuilder app)
{
    app.RunProxy(context => context
        .ForwardTo("http://upstream-server:5001/")
        .AddXForwardedHeaders()
        .Send());
}

This will add X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Proto headers to the upstream request using values from HttpContext. If the proxy middleware is hosted on a path and a PathBase exists on the request, then an X-Forwarded-PathBase is also added.

2.3.3. Copying X-Forwarded headers

Chaining proxies is a common pattern in more complex setups. In this case, if the proxy is an "internal" proxy, you will want to copy the "X-Forwarded-*" headers from previous proxy. To do so, use CopyXForwardedHeaders():

csharp
public void Configure(IApplicationBuilder app)
{
    app.RunProxy(context => context
        .ForwardTo("http://upstream-server:5001/")
        .CopyXForwardedHeaders()
        .Send());
}

You may optionally also add the "internal" proxy details to the X-Forwarded-* header values by combining CopyXForwardedHeaders() and AddXForwardedHeaders() (note the order is important):

csharp
public void Configure(IApplicationBuilder app)
{
    app.RunProxy(context => context
        .ForwardTo("http://upstream-server:5001/")
        .CopyXForwardedHeaders()
        .AddXForwardedHeaders()
        .Send());
}

2.4. Configuring ProxyKit's HttpClient

When adding the Proxy to your application's service collection, there is an opportunity to configure the internal HttpClient. As HttpClientFactory is used, its builder is exposed for you to configure:

csharp
services.AddProxy(httpClientBuilder => /* configure http client builder */);

Below are two examples of what you might want to do:

  1. Configure the HTTP Client's timeout to 5 seconds:

    csharp
    services.AddProxy(httpClientBuilder =>
        httpClientBuilder.ConfigureHttpClient =
            client => client.Timeout = TimeSpan.FromSeconds(5));
  2. Configure the primary HttpMessageHandler. This is typically used in testing to inject a test handler (see Testing below).

    csharp
    services.AddProxy(httpClientBuilder =>
        httpClientBuilder.ConfigurePrimaryHttpMessageHandler = 
            () => _testMessageHandler);

2.5. Error handling

When HttpClient throws, the following logic applies:

  1. When upstream server is not reachable, then 503 ServiceUnavailable is returned.
  2. When upstream server is slow and client timeouts, then 504 GatewayTimeout is returned.

Not all exception scenarios and variations are caught, which may result in a InternalServerError being returned to your clients. Please create an issue if a scenario is missing.

2.6. Testing

As ProxyKit is a standard ASP.NET Core middleware, it can be tested using the standard in-memory TestServer mechanism.

Often you will want to test ProxyKit with your application and perhaps test the behaviour of your application when load balanced with two or more instances as indicated below.

…

RoutingMessageHandler is an HttpMessageHandler that will route requests to specific hosts based on the origin it is configured with. For ProxyKit to forward requests (in memory) to the upstream hosts, it needs to be configured to use the RoutingMessageHandler as its primary HttpMessageHandler.

Full example can been viewed in Recipe 6.

2.7. Load Balancing

Load balancing is a mechanism to decide which upstream server to forward the request to. Out of the box, ProxyKit currently supports one type of load balancing - Weighted Round Robin. Other types are planned.

2.7.1. Weighted Round Robin

Round Robin simply distributes requests as they arrive to the next host in a distribution list. With optional weighting, more requests are sent to the host with the greater weight.

csharp
public void Configure(IApplicationBuilder app)
{
    var roundRobin = new RoundRobin
    {
        new UpstreamHost("http://localhost:5001/", weight: 1),
        new UpstreamHost("http://localhost:5002/", w

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

C#aspnetcoredotnetmiddlewareobsolete-soon

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言