简体   繁体   中英

How do I get a callback like AfterSessionComplete with Titanium-Web-Proxy

I used to use another proxy server library with C# to capture HTTP request, and it only has a AfterSessionComplete event which fires after the whole request/response action has all finished, and you can get the the host, path and query, request and response body all from the event argument. However that library stopped maintenancing sometime ago so I am considering switching to Titanium-Web-Proxy , and seems like it has a AfterResponse event. Here is what I used to test:

        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();
        }

And it does not work. The HTTP traffic will jam randomly: some request does not trigger AfterResponse event, says pending in Chrome DevTools and eventually timeout. Even with requests that made to the server, I am not getting the request and response body, which trying to get them will trigger exceptions like:

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.

I also tried await GetRequestBodyAsString() and await GetResponseBodyAsString() but still nothing. In that stage I am pretty confused, what should I do actually? Do I need to ditch AfterResponse and use the other events provided?

In Titanium, the AfterResponse event marks a moment when the response was sent to the browser (and is no longer available). So to read the response body, you need to attach to the BeforeResponse event. Additionally, as you observed, you can't access the request body in the* Response events. One option to overcome this limitation is to use the UserData property and, in the BeforeRequest event, save all the data from the request body that you may later need. The example code below shows how to do that:

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.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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