vaiperboy
vaiperboy

Reputation: 88

HttpClient / HttpRequestMessage adding white spaces to headers

I just got into .net core due to the features it has to offer for HttpClient (example is setting the keep-alive header capped down). I'm using 2.1 net core and C# 7.3

My issue

My issue is specifically about setting the "Accept" and "Accept-Language" headers. The site I'm trying to reach parses these two headers as is, meaning it must have the same exact format (including spaces).

Using fiddler (and some other tools) to grab my request.

  1. I'm capturing the "Accept" header as the following: (incorrect format)
text/html, application/xhtml+xml, application/xml; q=0.9, image/webp, image/apng, */*; q=0.8, application/signed-exchange; v=b3

instead of: (correct format)

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
  1. "Accept-Language" header as the following: (incorrect format)
en-US, en; q=0.9, ar; q=0.8, und; q=0.7

Instead of: (correct format)

en-US,en;q=0.9,ar;q=0.8,und;q=0.7

I'm simulating a GET request using HttpClient with the help of HttpRequestMessage.

What I have tried

  1. Tried both settings my headers in the HttpClient instance and firing off a HttpRequestMessage with it's own headers, none are working.
  2. Tried lots of solutions online which didn't work, including this
  3. Splitting the header through multiple .Headers.TryAddWithoutValidation
  4. Tried HttpWebRequests as well. No luck. One thing to note, due to my project I also like to stick with the HttpClient.

You'll find below my current code

var client = new HttpClient(new HttpClientHandler() { UseCookies = false,
            AllowAutoRedirect = false,
            Proxy = new WebProxy("localhost:8888") });

var httpReq = new HttpRequestMessage(HttpMethod.Get, $"myurl");


            httpReq.Headers.TryAddWithoutValidation("Host", "myurl");
            httpReq.Headers.TryAddWithoutValidation("Connection", "keep-alive");
            httpReq.Headers.TryAddWithoutValidation("Cookie", $"cookie");
            httpReq.Headers.TryAddWithoutValidation("Upgrade-Insecure-Requests", "1");
            httpReq.Headers.TryAddWithoutValidation("User-Agent", Data.user_agent);
            httpReq.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate, br");
            httpReq.Headers.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
            httpReq.Headers.TryAddWithoutValidation("Referer", Data.homeUrl);
            httpReq.Headers.TryAddWithoutValidation("Accept-Language", "en-US,en;q=0.9,ar;q=0.8,und;q=0.7");

            req = await client.SendAsync(httpReq);

As noted before, all the other headers are working fine. Just these two Accept and Accept-Language are being inputted differently.

Upvotes: 5

Views: 1867

Answers (1)

JOSEFtw
JOSEFtw

Reputation: 10091

It seems like it's hardcoded in corefx, look here:

destination.Append(' ');

Full method:

internal static void ToString(ObjectCollection<NameValueHeaderValue> values, char separator, bool leadingSeparator,
            StringBuilder destination)
        {
            Debug.Assert(destination != null);

            if ((values == null) || (values.Count == 0))
            {
                return;
            }

            foreach (var value in values)
            {
                if (leadingSeparator || (destination.Length > 0))
                {
                    destination.Append(separator);
                    destination.Append(' ');
                }
                value.AddToStringBuilder(destination);
            }
        }

https://github.com/dotnet/corefx/blob/a10890f4ffe0fadf090c922578ba0e606ebdd16c/src/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs#L183

I don't know how to override this but maybe you could create a new issue on GitHub?

EDIT: Found an issue regarding this and bumped it: https://github.com/dotnet/corefx/issues/18449

Upvotes: 3

Related Questions