简体   繁体   English

如何创建简单的IIS站点以将所有调用重定向到另一个服务?

[英]How to create simple IIS site to redirect all calls to another service?

I've written a REST API service in Delphi, which runs as its own stand-alone service. 我已经在Delphi中编写了REST API服务,该服务作为其自己的独立服务运行。 I also have IIS hosting some sites on port 80 . 我也有IIS在端口80上托管一些站点。 I would like to use port 80 for my REST API as well, but since I'm already using it in IIS, I'm forced to use another port. 我也想将端口80用于我的REST API,但是由于我已经在IIS中使用它,因此不得不使用其他端口。

What I'd like to do to overcome this is create a very simple site in IIS (Preferably with ASP.NET/C#) which simply redirects all incoming HTTP requests to this other service running on a different port. 我想解决的方法是在IIS中创建一个非常简单的站点(最好使用ASP.NET/C#),该站点将所有传入的HTTP请求重定向到在其他端口上运行的该其他服务。 This would allow me to take advantage of binding multiple sites under the same port in IIS. 这将使我能够利用在IIS中同一端口下绑定多个站点的优势。 I don't want to perform a literal "redirect", but just replicate the request to the desired server, and respond back - as if user was connecting to original REST server. 我不想执行原义的“重定向”,而只是将请求复制到所需的服务器,然后进行响应-就像用户正在连接到原始REST服务器一样。 Only, without having to use a non-standard port. 仅,而不必使用非标准端口。 The URL on the client-side shouldn't change (as what you normally see with an HTTP Redirect). 客户端的URL不应更改(如您通常在HTTP重定向中看到的那样)。

Essentially, if user makes such a request: 本质上,如果用户发出这样的请求:

http://api.mydomain.com/SomeReq?some=query

It will turn around and make a corresponding request to the real server, and carry over the entire URI - just a different port number: 它将转过来向真实服务器发出相应的请求,并保留整个URI-只是一个不同的端口号:

http://api.mydomain.com:8664/SomeReq?some=query

How can I accomplish this? 我该怎么做?

Using ASP.NET Web API it is pretty simple to write such a proxy server. 使用ASP.NET Web API,编写这样的代理服务器非常简单。 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/* . 在此示例中,代理将侦听:80/proxy/*并将其转发到:8664/*

So if you send the following request to your Web API: 因此,如果您将以下请求发送到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/* . 这也适用于POST和其他对: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. 显然,如果您要将整个Web服务器变成代理并侦听:80/*则可以摆脱在示例中使用的/proxy前缀。

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. 在实际的生产系统中,我会将这项任务卸载到专门为此目的而设计的功能HAProxy前端负载均衡器(例如nginxHAProxy中。 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. 然后,您的IIS和Delphi应用程序都可以侦听任意端口,并将您的nginx配置为侦听端口80,并根据某些模式将流量转发到后端节点。 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). 使用负载均衡器还有其他好处,就像您有多个后端节点一样,它将在它们之间分配负载,还使您可以在不停机的情况下对应用程序进行更新(因为您可以完全控制哪个节点位于其中负载平衡器池)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM