使用OWIN创建代理服务器

时间:2018-01-25 04:48:59

标签: c# owin http-proxy

要求

组织有代理,需要身份验证。

第三方软件支持代理,但不支持代理身份验证。

因此,我们希望编写一个小型代理程序,将第三方软件的请求委托给组织代理。

(我们使用OWIN自托管服务。该项目是一个控制台应用程序)

类ProxyHandler

using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

...

public class ProxyHandler : DelegatingHandler
{
    public static IWebProxy Proxy { get; set; }
    public ProxyHandler()
    {

    }
    protected override async Task<HttpResponseMessage>
        SendAsync(HttpRequestMessage req, CancellationToken ct)
    {
        var fwd = new UriBuilder(req.RequestUri);
        fwd.Port = 443; //The software uses https only; 
                        //in the test below this is not even called so does not matter

        req.RequestUri = fwd.Uri;

        var h = new HttpClientHandler();
        h.UseCookies = true;
        h.AllowAutoRedirect = true;
        h.Proxy = Proxy;
        var c = new HttpClient(h);
        var resp = await c.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
        return resp;
    }
}

类Startup

using Owin;
using System.Net.Http;
using System.Web.Http;

...

class Startup
{
    public void Configuration(IAppBuilder b)
    {
        var cfg = new HttpConfiguration();
        cfg.Routes.MapHttpRoute(
            "Proxy",
            "{*path}",
            new {path=RouteParameter.Optional},
            null,
            HttpClientFactory.CreatePipeline(
                new HttpClientHandler(),
                new DelegatingHandler[] { }
            ));
        b.UseWebApi(cfg);
    }
}

启动代理服务并通过下载进行测试的代码

using Microsoft.Owin.Hosting;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

...

        var p = new WebProxy(proxy_uri, true)
        {
            Credentials = new NetworkCredential(domain_user, password)
        };
        ProxyHandler.Proxy = p;
        var app = WebApp.Start<Startup>("http://localhost:8181/");

        using (app)
        {
            var wc = new WebClient();
            wc.Proxy = new WebProxy("localhost:8181", true);

            var downloaded = await wc.DownloadStringTaskAsync
                (new Uri("http://example.com/));
            Console.WriteLine(downloaded);
        }

结果

wc.DownloadStringTaskAsync的调用会引发HTTP 400错误。根本没有调用SendAsync方法。

问题

我怎样才能让它发挥作用?

0 个答案:

没有答案