Bug 47599 - HttpClient Transfer-Encoding:chunked is not added to the header - not able to transfer large files
Summary: HttpClient Transfer-Encoding:chunked is not added to the header - not able to...
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Net.Http ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Marek Safar
URL:
Depends on:
Blocks:
 
Reported: 2016-11-21 20:29 UTC by titus.aries
Modified: 2017-02-15 12:17 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description titus.aries 2016-11-21 20:29:38 UTC
In the UWP app the header is present see below:
Hypertext Transfer Protocol
    POST / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): POST / HTTP/1.1\r\n]
        Request Method: POST
        Request URI: /
        Request Version: HTTP/1.1
    Content-Type: application/octetstream\r\n
    Content-Disposition: form-data; name=file.rar; filename=file.rar; filename*=utf-8''file.rar\r\n
    Host: server.local\r\n
    Connection: Keep-Alive\r\n
    Transfer-Encoding: chunked\r\n
    \r\n
    [Full request URI: http://server.local/]
    [HTTP request 2/2]
    HTTP chunked response
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)
        Data chunk (65536 octets)

But in Android the header is not added:
Hypertext Transfer Protocol
    POST / HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): POST / HTTP/1.1\r\n]
            [POST / HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: POST
        Request URI: /
        Request Version: HTTP/1.1
    Content-Type: application/octetstream\r\n
    Content-Length: 13104524\r\n
        [Content length: 13104524]
    Connection: keep-alive\r\n
    Host: server.local\r\n
    \r\n
    [Full request URI: http://server.local/]
    [HTTP request 2/2]
    File Data: 13104524 bytes
Comment 1 titus.aries 2016-11-28 18:56:41 UTC
Hi,

Any update?

Thanks,
Titus
Comment 2 Marek Safar 2017-01-10 17:24:55 UTC
Which Android handler are you using ?

How can I reproduce the issue ?
Comment 3 titus.aries 2017-01-11 09:55:26 UTC
This is the code used, I tried multiple ways to add the header without success. I wrote this code in the portable project and tested with the Visual Studio 2015 Android Emulator.

            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
            var imageContent = new StreamContent(Android.App.Application.Context.Assets.Open(@"file.rar")); //large file

            imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octetstream");
            imageContent.Headers.TryAddWithoutValidation("Transfer-Encoding", "chunked");
            string url = @"http://x.x.x.x/"; //web server address
            HttpResponseMessage message = await httpClient.PostAsync(url, imageContent);

            //HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);
            //request.Content = imageContent;
            //request.Headers.TransferEncodingChunked = true;
            //request.Headers.Add("Transfer-Encoding", "chunked");
            //await httpClient.SendAsync(request);
Comment 4 titus.aries 2017-02-07 18:25:34 UTC
Info provided.
Comment 5 Marek Safar 2017-02-08 14:33:36 UTC
I can reproduce it using the repro and it looks like the handling done https://github.com/mono/mono/blob/4c6c6f0ef80a0db497908d60bea5a30a47f3290a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs#L297 is just to simple to cover this case.

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

namespace Console35
{
	class MainClass
	{
		public static void Main (string [] args)
		{
			Run ().Wait ();
		}

		static async Task Run ()
		{
			var httpClient = new HttpClient ();
			httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
			var imageContent = new StreamContent (File.OpenRead ("/Users/foooo/Downloads/System.dll"));

			imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse ("application/octetstream");
			imageContent.Headers.TryAddWithoutValidation ("Transfer-Encoding", "chunked");
			string url = @"http://httpbin.org/post"; //web server address
			HttpResponseMessage message = await httpClient.PostAsync (url, imageContent);

			return;
		}
	}
}
Comment 6 Marek Safar 2017-02-15 12:17:32 UTC
Fixed in master