How to process the HttpClient.PostAsync file to download files in bad network conditions?

I am working on developing a mobile application that focuses on uploading multiple photos to an api web application. I use Xamarin.Forms and System.Net.Http.HttpClient and Clumsy to simulate bad network conditions (lag, dropped packets, out-of-order packets). The application was originally written using Titanium and worked great for most users, but some users on poor mobile networks often encountered bugs. In the future, we will port Xamarin and try to accommodate users with poor connectivity.

using (var httpClient = CreateClient()) { httpClient.Timeout = TimeSpan.FromMinutes(5); using (var formData = new MultipartFormDataContent()) { // add required fields via formData.Add() ... var httpContent = new ByteArrayContent(imageData); formData.Add(httpContent, "file", Guid.NewGuid() + ".jpg"); try { var response = await httpClient.PostAsync("fileupload", formData).ConfigureAwait(false); if (response.IsSuccessStatusCode) { responseObject = await ResponseMessageToResponseModel(response).ConfigureAwait(false); } } catch (HttpRequestException ex) { Debug.WriteLine("HttpRequestException"); } catch (TaskCanceledException ex) { Debug.WriteLine("TaskCanceledException"); } } } 

What I find is that everything works as expected under normal conditions; when you turn on Clumsy with a β€œdelay, drop out, fail” and try to load PostAsync () never completes and ultimately ends with a TaskCanceledException. The strange thing is that the file gets to the server .. so the POST data apparently went through everything.

I assume that packets dropped in the response from the server mean that the HttpClient never receives the proper response and continues to wait alone until the time runs out.

To understand this, I wonder if anyone has any ideas on how to make this process as valid as possible. Just catching a timeout and retrying is not very good if the file did this for the first time. Any thoughts?

Also, any information on how HttpClient handles dropped / invalid packets, so I can better understand what will happen in this case too.

+6
source share
1 answer

One thing with HttpClient I hit my head while I was special (read unusual) POST request processing. When sending a POST request, it first sends headers (including ContentLenght and a special Expect: 100-continue header) to the server, but without the body. And it expects the server to respond with a status code of 100 if the request is acceptable. After that, he begins to send the body. More information here: MSDN page for ServicePointManager.Expect100Continue MSDN blog post with some details

In my case, the problem was that this part of the protocol was poorly handled by the backend service (Play framework), which I talked to when the request size was too large to process. He did not return any errors. And the request is just timed. Therefore disable it ServicePointManager.Expect100Continue = false; long before sending any request this host solved the problem for me. At least now he was returning something.

If this does not help, then the best thing I can recommend is looking with wirehark or something similar while what happens on the wire. If he plays well with this Clumsy instrument that you use. (Thanks for the link, by the way, I was also looking for something like that)

+1
source

Source: https://habr.com/ru/post/983334/


All Articles