【问题标题】:HttpClient / HttpRequestMessage adding white spaces to headersHttpClient / HttpRequestMessage 向标头添加空格
【发布时间】:2019-09-13 22:19:52
【问题描述】:

我刚刚进入 .net 核心,因为它必须为 HttpClient 提供功能(例如将 keep-alive 标头设置为上限)。 我使用的是 2.1 net core 和 C# 7.3

我的问题

我的问题特别是关于设置“Accept”和“Accept-Language”标题。我试图访问的站点按原样解析这两个标头,这意味着它必须具有相同的确切格式(包括空格)。

使用提琴手(和其他一些工具)来获取我的请求。

  1. 我正在捕获“Accept”标头,如下所示:(格式不正确)
text/html, application/xhtml+xml, application/xml; q=0.9, image/webp, image/apng, */*; q=0.8, application/signed-exchange; v=b3

而不是:(正确的格式)

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”标头如下:(格式不正确)
en-US, en; q=0.9, ar; q=0.8, und; q=0.7

而不是:(正确的格式)

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

我在 HttpRequestMessage 的帮助下使用 HttpClient 模拟 GET 请求。

我的尝试

  1. 尝试了两种设置我在 HttpClient 实例中的标头并使用它自己的标头触发 HttpRequestMessage,但都没有工作。
  2. 在线尝试了很多解决方案都不起作用,包括this
  3. 通过多个.Headers.TryAddWithoutValidation拆分标题
  4. 也尝试过 HttpWebRequest。没有运气。 需要注意的一点是,由于我的项目,我也喜欢坚持使用 HttpClient。

您会在我当前的代码下方找到

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

如前所述,所有其他标头工作正常。只是这两个 Accept 和 Accept-Language 的输入方式不同。

【问题讨论】:

  • 您是否尝试过使用httpReq.Headers.AcceptLanguage.Add("en-US"); 等单独添加标题?
  • @spodger,是的。我也试过了。它不应该影响我的输入,因为它只与标题名称而不是值有关?
  • 请不要“碰”问题
  • 尝试在 Postman 中生成请求,生成 C# 代码并与你的比较。
  • @mr5 在使用 postman 的 C# 生成代码(使用 restclient)时输出相同的结果,在标题中添加空格。

标签: c# .net-core httpclient


【解决方案1】:

好像是在 corefx 中硬编码的,看这里:

destination.Append(' ');

完整方法:

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

我不知道如何覆盖它,但也许你可以在 GitHub 上创建一个新问题?

编辑:发现了一个关于此的问题并遇到了问题:https://github.com/dotnet/corefx/issues/18449

【讨论】:

  • 似乎添加分隔符的人可能已经从 RFC7231#section-5.3 中提供的示例中提取了它。 5.3 中没有提到空格处理,尽管在其他部分中明确给出了对空格的处理,并且当提到它时,它提供了指导,当提供的空格将无效或被接收者忽略时。可能应该更改分隔符以匹配基本约定:当主要收件人不是人类时,应避免不必要的空格。
  • @K.AlanBates 我在 GitHub 上发现了这个问题,他们正在讨论这个问题:github.com/dotnet/corefx/issues/18449
  • 感谢您指出问题报告实际上已生成(幸好我不是唯一的人?)。我看看能不能直接向微软举报@JOSEFtw
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 2017-12-30
  • 2012-08-14
相关资源
最近更新 更多