【问题标题】:How do I get a callback like AfterSessionComplete with Titanium-Web-Proxy如何使用 Titanium-Web-Proxy 获得类似 AfterSessionComplete 的回调
【发布时间】:2020-10-01 21:49:47
【问题描述】:

我曾经使用另一个带有 C# 的代理服务器库来捕获 HTTP 请求,它只有一个 AfterSessionComplete 事件,该事件在整个请求/响应操作全部完成后触发,您可以获得主机、路径和查询、请求和响应正文都来自事件参数。然而,该库前一段时间停止维护,所以我正在考虑切换到Titanium-Web-Proxy,并且似乎它有一个AfterResponse 事件。这是我曾经测试过的:

        private static async Task Server_AfterResponse(object sender, SessionEventArgs e)
        {
            try
            {
                Uri url = e.HttpClient.Request.RequestUri;
                string method = e.HttpClient.Request.Method.ToUpper();
                string req = e.HttpClient.Request.HasBody ? e.HttpClient.Request.BodyString : null;
                string resp = e.HttpClient.Response.HasBody ? e.HttpClient.Response.BodyString : null;
                ThreadPool.QueueUserWorkItem(new WaitCallback((s) =>
                {
                    // Goes back to my old AfterSessionComplete method.
                    HttpProxy.AfterSessionComplete?.Invoke(url, method, req, resp);
                }));
            }
            catch(Exception ex)
            {
                Debug.Print($"{ex}");
            }
        }

        public static void Start(int port = 37123)
        {
            HttpProxy.server = new ProxyServer(false, false, false);
            HttpProxy.server.AddEndPoint(new ExplicitProxyEndPoint(IPAddress.Any, port, false));
            HttpProxy.server.AfterResponse += Server_AfterResponse;
            HttpProxy.server.Start();
        }

而且它不起作用。 HTTP 流量会随机阻塞:一些请求不会触发 AfterResponse 事件,在 Chrome DevTools 中显示为挂起并最终超时。即使向服务器发出请求,我也没有得到请求和响应正文,试图获取它们会触发异常,例如:

System.Exception: You cannot get the request body after request is made to server.

System.Exception: Response body is not read yet. Use SessionEventArgs.GetResponseBody() or SessionEventArgs.GetResponseBodyAsString() method to read the response body.

我也尝试了await GetRequestBodyAsString()await GetResponseBodyAsString(),但仍然没有。在那个阶段我很困惑,我该怎么办?我需要放弃AfterResponse 并使用提供的其他事件吗?

【问题讨论】:

    标签: c# titanium-web-proxy


    【解决方案1】:

    在 Titanium 中,AfterResponse 事件标志着响应被发送到浏览器的时刻(并且不再可用)。因此,要读取响应正文,您需要附加到 BeforeResponse 事件。此外,正如您所观察到的,您无法在* Response 事件中访问请求正文。克服此限制的一种方法是使用 UserData 属性,并在 BeforeRequest 事件中保存您以后可能需要的请求正文中的所有数据。下面的示例代码显示了如何做到这一点:

    void Main()
    {
        var proxyServer = new ProxyServer(userTrustRootCertificate: false);
    
        proxyServer.BeforeRequest += OnBeforeRequest;
        proxyServer.BeforeResponse += OnBeforeResponse;
    
        var httpProxy = new ExplicitProxyEndPoint(IPAddress.Loopback, 8080, decryptSsl: true);
    
        proxyServer.AddEndPoint(httpProxy);
        proxyServer.Start();
    
        Console.ReadLine();
    
        proxyServer.Stop();
    }
    
    // Define other methods and classes here
    
    public async Task OnBeforeRequest(object sender, SessionEventArgs ev)
    {
        var request = ev.HttpClient.Request;
    
        ev.UserData = request.HasBody ? await ev.GetRequestBodyAsString() : "";
    }
    
    public async Task OnBeforeResponse(object sender, SessionEventArgs ev)
    {
        var request = ev.HttpClient.Request;
        var response = ev.HttpClient.Response;
    
        var requestBody = (string)ev.UserData;
        var responseBody = response.HasBody ? await ev.GetResponseBodyAsString() : "";
    
        // TODO: Your old AfterSessionComplete method.
    }
    

    【讨论】:

    • 好的,我想现在我理解了工作程序。 HTTP 数据包的其他参数(如主机、路径和查询、方法等)被保存并可以在AfterResponse 中访问,但在正文数据传输到其目的地之前,必须动态读取和保存请求和响应正文,是对吗?
    • 谢谢,虽然我已经回到了以前使用的库,但后来我尝试了您的解决方案,它完美无缺。
    猜你喜欢
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多