Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# httpclient post force single packet

Using Microsoft Message Analyzer, I can see that post data using the HttpClient is being sent in two tcp packets. One for the header, then one for the post data. This data could easily fit into one packet, however it is being split into two. I have explicitly turned on nagling and expect 100 continue off using the ServicePointManager, though, it doesn't seem to help.

        ServicePointManager.Expect100Continue = false;
        ServicePointManager.UseNagleAlgorithm = true;

Microsoft Message Analyzer 5023 (.Net) shows 2 packets are sent to destination, 8170 (Postman) shows 1 packet being sent. Tests were done with the same payload.

Below is some sample code used to generate the request in .net

    public void TestRequest()
    {
        var uri = new Uri("http://www.webscantest.com/");
        ServicePointManager.Expect100Continue = false;
        ServicePointManager.UseNagleAlgorithm = true;
        var p = ServicePointManager.FindServicePoint(uri);
        p.Expect100Continue = false;
        p.UseNagleAlgorithm = true;
        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Add("Connection", "close");

        var values = new Dictionary<string, string>
        {
            { "thing1", "hello" },
            { "thing2", "world" }
        };

        var content = new FormUrlEncodedContent(values);

        var response = client.PostAsync("http://www.webscantest.com/", content, CancellationToken.None).Result;
    }

Is there a way to force the payload into a single packet?

Using .Net Framework 4.7

related question here

like image 934
Calvin Pietersen Avatar asked Apr 09 '18 07:04

Calvin Pietersen


1 Answers

So after looking at the dotnet core source code (can only assume the same in other .net versions), I can see in the WinHttpHandler that the Request Header and Request Body are sent at different points.

The request header is sent with Interop.WinHttp.WinHttpSendRequest. Then the request body with Interop.WinHttp.WinHttpWriteData which according to the WinHttp docs, will "Wait until WinHttpSendRequest has completed before calling this function".

I think this issue could be solved, if the request body was sent with the WinHttpSendRequest, which currently sets the body as IntPtr.Zero.

Request Header here

Request Body here

like image 167
Calvin Pietersen Avatar answered Oct 20 '22 15:10

Calvin Pietersen