Using ASP.NET Web API it is pretty simple to write such a proxy server. All you need is a delegating handler:
public class ProxyHandler : DelegatingHandler
{
private static HttpClient client = new HttpClient();
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
// strip the /proxy portion of the path when making the request
// to the backend node because our server will be made to listen
// to :80/proxy/* (see below when registering the /proxy route)
var forwardUri = new UriBuilder(request.RequestUri.AbsoluteUri.Replace("/proxy", string.Empty));
// replace the port from 80 to the backend target port
forwardUri.Port = 8664;
request.RequestUri = forwardUri.Uri;
if (request.Method == HttpMethod.Get)
{
request.Content = null;
}
// replace the Host header when making the request to the
// backend node
request.Headers.Host = "localhost:8664";
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
return response;
}
}
and finally all that's left is to register this handler:
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "proxy/{*path}",
handler: HttpClientFactory.CreatePipeline(
innerHandler: new HttpClientHandler(),
handlers: new DelegatingHandler[]
{
new ProxyHandler()
}
),
defaults: new { path = RouteParameter.Optional },
constraints: null
);
In this example the proxy will listen on :80/proxy/*
and forward it to :8664/*
.
So if you send the following request to your Web API:
GET http://localhost:80/proxy/SomeReq?some=query HTTP/1.1
Host: localhost:80
Connection: close
it will be translated to:
GET http://localhost:8664/SomeReq?some=query HTTP/1.1
Host: localhost:8664
Connection: close
This will also work for POST and other verbs made to :80/proxy/*
.
Obviously if you want to turn your entire webserver into a proxy and listen to :80/*
then you could get rid of the /proxy
prefix that I used in my example.
This being said, this is only a proof-of-concept proxy server. In a real production system I would off-load this task to a full blown frontend load balancer such as nginx
or HAProxy
which are designed exactly for this purpose. Then both your IIS and Delphi application could listen on arbitrary ports and your nginx configured to listen to port 80 and forward the traffic to the backend node(s) based on some patterns. Using a load balancer also has other benefits as if you are having multiple backend nodes, it will distribute the load between them and also give you the possibility to make updates to your applications without any downtime (because you have full control over which node is in the load balancer pool).