我正在努力解决这个错误:https:
//github.com/openstacknetsdk/openstack.net/issues/333
该问题涉及ProtocolViolationException
以下消息:
HTTP/1.0协议不支持分块编码上载.
我发现我能够可靠地重现我发出生成502响应代码的Web请求的问题,然后调用使用带有分块编码的POST请求.我将其追溯到ServicePoint.HttpBehaviour
具有HttpBehaviour.HTTP10
502响应之后的值的属性.
我能够使用以下hack解决问题(在catch
块中).此代码"隐藏" ServicePoint
由失败请求创建的实例ServicePointManager
,强制它ServicePoint
为下一个请求创建新的实例.
public void TestProtocolViolation()
{
try
{
TestTempUrlWithSpecialCharactersInObjectName();
}
catch (WebException ex)
{
ServicePoint servicePoint = ServicePointManager.FindServicePoint(ex.Response.ResponseUri);
FieldInfo table = typeof(ServicePointManager).GetField("s_ServicePointTable", BindingFlags.Static | BindingFlags.NonPublic);
WeakReference weakReference = (WeakReference)((Hashtable)table.GetValue(null))[servicePoint.Address.GetLeftPart(UriPartial.Authority)];
if (weakReference != null)
weakReference.Target = null;
}
TestTempUrlExpired();
}
Run Code Online (Sandbox Code Playgroud)
问题:
ServicePointManager.ServerCertificateValidationCallback
是一个全局静态属性,只需执行以下操作即可被应用程序中的任何代码覆盖:
ServicePointManager.ServerCertificateValidationCallback
= (sender, cert, chain, sslPolicyErrors) => true;
Run Code Online (Sandbox Code Playgroud)
他们为什么决定以这种方式实施?当然它应该是WebRequest
对象的属性,你应该有一个很好的理由来解释为什么你忽略了证书.
使用Microsoft Message Analyzer,我可以看到使用HttpClient发布的数据是以两个tcp数据包发送的.一个用于标题,然后一个用于发布数据.这些数据很容易适合一个数据包,但它被分成两个.我明确地打开了唠叨,并期望100继续使用ServicePointManager,但它似乎没有帮助.
ServicePointManager.Expect100Continue = false;
ServicePointManager.UseNagleAlgorithm = true;
Run Code Online (Sandbox Code Playgroud)
5023(.Net)显示2个数据包被发送到目的地,8170(邮递员)显示1个数据包被发送.测试是使用相同的有效负载完成的.
下面是一些用于在.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;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法强制有效载荷成为一个数据包?
使用.Net Framework 4.7
我有以下代码.
public void Submit(string XML)
{
ServicePointManager.ServerCertificateValidationCallback = ValidateCertificate;
TestWS.CW serv = new TestWS.CW();
string s = serv.Check(XML);
}
private static bool ValidateCertificate(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
}
Run Code Online (Sandbox Code Playgroud)
但是,代码永远不会进入ValidateCertificate
方法....如果我提交标准,HttpsWebRequest
但如果我使用Web服务它不起作用.我究竟做错了什么?
我想在我的WPF应用程序中显示用户Gravatar.这就是我绑定Image-Control的方式:
<Image Source="{Binding Path=Email, Converter={StaticResource GravatarConverter},IsAsync=True}">
Run Code Online (Sandbox Code Playgroud)
GravatarConverter返回给定电子邮件的URL.不幸的是,这在加载第一张图片时完全阻止了我的UI.请注意我使用"IsAsync = True".经过一些研究后,我发现在应用程序启动时在一个单独的线程中调用FindServicePoint时,我可以解决这个问题:
Task.Factory.StartNew( () => ServicePointManager.FindServicePoint( "http://www.gravatar.com", WebRequest.DefaultWebProxy ) );
Run Code Online (Sandbox Code Playgroud)
但是当我的应用程序已经下载图像时,当FindServicePoint没有完成时,这不起作用.有人可以解释为什么WPF-App完全需要这个FindServicePoint,为什么这会阻止UI以及如何避免阻塞?
谢谢
更新:事实证明,当我在Internet Explorers"Internet选项" - >"连接" - >"局域网设置"中取消选中"自动检测设置"后,我的问题就消失了.
我使用这个非常简单的WPF应用程序来重现问题,只需在文本框中插入图像的URL并单击按钮即可.启用"自动检测设置"后,应用程序会在第一次加载图像时冻结几秒钟.使用此选项可立即禁用其加载.
MainWindow.xaml
<Window x:Class="WpfGravatarFreezeTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" x:Name="tbEmail" />
<Button Grid.Column="0" Grid.Row="0" Click="buttonLoad_OnClick" HorizontalAlignment="Right">Set Source</Button>
<Image x:Name="img" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Media.Imaging;
namespace WpfGravatarFreezeTest …
Run Code Online (Sandbox Code Playgroud) 我想关闭特定连接上的 Nagle 算法(在我的情况下 - 到 ElasticSearch 服务器)。
我的代码目前看起来像这样:
ServicePointManager.FindServicePoint(new Uri(uriWithoutLocalPath)).UseNagleAlgorithm = false;
Run Code Online (Sandbox Code Playgroud)
问题是ServicePoint
对象在一段时间后被回收,导致它丢失设置。因此,我不能在系统启动时只运行一次此代码。看来我面前有几个选择:
ServicePoint
永远不会回收(可能是个坏主意?我的直觉告诉我)。ServicePoint
。我真的不喜欢这些选项中的任何一个,它们要么会影响系统中的其他东西,要么看起来对于我想要做的事情来说太复杂了(比如计时器选项)。在我看来,应该有一个简单的解决方案。想法?
更新 C# 从 NET 5 升级到 6 后开始出现此错误 -
警告 SYSLIB0014“ServicePointManager.FindServicePoint(Uri)”已过时:“WebRequest、HttpWebRequest、ServicePoint 和 WebClient 已过时。请改用 HttpClient。
var servicePoint = ServicePointManager.FindServicePoint(requestUri.GetEndpoint());
if (servicePoint.ConnectionLeaseTimeout == -1){}
Run Code Online (Sandbox Code Playgroud) 执行该行时,Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html
PowerShell throws抛出WebCmdletResponseException
。我如何获得有关它的更多信息,这可能是什么原因造成的?虽然我可以使用Python成功获取页面的内容,但是在PowerShell中会引发异常。
完全例外:
Run Code Online (Sandbox Code Playgroud)Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send. At line:1 char:1 + Invoke-WebRequest -Uri https://www.freehaven.net/anonbib/date.html + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc eption + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
c# ×5
httpclient ×2
servicepoint ×2
.net ×1
c#-6.0 ×1
image ×1
post ×1
powershell ×1
ssl ×1
tcp ×1
tls1.2 ×1
wpf ×1