如何解决使用HttpClient,客户端证书和WinHttpHandler将HTTP / 2请求发送到Apple Push Notification Service会引发HttpRequestException
我正在尝试编写一些代码,以通过C#.NET和HttpClient通过具有客户端证书身份验证的HTTP向iPhone发送推送通知。
代码会编译,但始终会产生一个:
带有消息“将内容复制到流时出错”的HttpRequestException。
InnerException IOException消息“写入操作失败,请参阅内部异常。”
InnerException WinHttpException消息“ {”错误12152调用WinHttpWriteData,'服务器返回了无效或无法识别的响应'。“}”
我在寻找代码失败的原因?
是否可以通过某种方式对此进行调试/故障排除?
这是我的代码
class Program {
private const string cert = "MIINKwI....<hidden>";
private const string certpw = "password";
private const string devicetoken = "921c95b6494828f973512f2327478b0<hidden>";
private const string bundleid = "se.jensolsson.testapp";
private static HttpClient client = null;
static async Task Main(string[] args) {
try {
byte[] certificateData = Convert.FromBase64String(cert);
X509Certificate2 certificate = new X509Certificate2(certificateData,certpw,X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
string url = "https://api.push.apple.com:443/3/device/";
string payload = @"{""aps"":{""alert"":""Test""}}";
var handler = new WinHttpHandler();
handler.ClientCertificates.Add(certificate);
if (client == null)
client = new HttpClient(handler);
using (var request = new HttpRequestMessage(HttpMethod.Post,url + devicetoken)) {
var messageGuid = Guid.NewGuid().ToString();
request.Version = new Version("2.0");
request.Content = new StringContent(payload);
request.Headers.Add("apns-id",messageGuid);
request.Headers.Add("apns-push-type","alert");
request.Headers.Add("apns-priority","10");
request.Headers.Add("apns-topic",bundleid);
using (var response = await client.SendAsync(request,HttpCompletionOption.ResponseHeadersRead)) {
HttpStatusCode statusCode = response.StatusCode;
string reasonPhrase = response.ReasonPhrase;
bool success = response.IsSuccessStatusCode;
}
}
}
catch (ArgumentNullException anu) { }
catch (InvalidOperationException ioe) { }
catch (HttpRequestException hre) { }
catch (TaskCanceledException tce) { }
catch (Exception e) { }
}
}
编辑 @jdweng实际上尝试过Wireshark,但是由于它是通过SSL加密的,所以我希望Wireshark无法读取它吗?我看到的是,连接是从客户端重置的,必须由基础框架完成。
编辑2: 进一步调查。尝试连接到支持HTTP2的开放式Web服务器。我以https://nghttp2.org/为例。
- 将网址行替换为
string url = "https://nghttp2.org/";
- 将请求行替换为
using (var request = new HttpRequestMessage(HttpMethod.Get,url)) {
。
一个非常有趣的发现是,即使我发送了HTTP / 2请求,并且它似乎给出了答复,看着响应对象,版本仍设置为1.1 。
如果我还删除了handler.ClientCertificates.Add(certificate);
行并重试,请查看响应对象,版本已正确设置为2.0 。
因此,一旦将客户端证书添加到处理程序中,WinHttpHandler似乎就放弃了对HTTP / 2的支持。
编辑3: 我现在假设这是框架中的错误,并且我在此处发布了错误报告:https://github.com/dotnet/runtime/issues/40794
解决方法
事实证明不支持此功能。 主要是因为Windows版本缺少功能。根据corefx团队github中的评论,此版本应在Windows版本2004(内部版本19573+ github discussion)下运行。此版本的问题在于它尚未发布,也没有计划何时发布。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。