我怎么能接受“不安全”呢?Windows Phone/Store应用中的HTTP响应头
本文关键字:不安全 应用 Store 响应 HTTP Phone Windows 能接受 | 更新日期: 2023-09-27 18:17:05
最近,使用HttpClient
访问第三方REST API的Windows Phone 8.1 Silverlight应用程序中的一些代码停止工作。我得到了以下错误:
类型为'System '的第一次异常。mscorlib.ni.dll出现异常
附加信息:灾难性失败(Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
在Windows Phone (Silverlight)和Store (RT)应用程序中尝试后,我在WPF中重写了相同的代码,最终得到了一个有用的错误消息:
服务器违反了协议。Section=ResponseHeader Detail=CR后面必须跟LF"
也有一篇很好的关于这个问题的深入的博客文章。
微软已经声明他们不会修复/允许这个,所以我要么被迫找到一个允许不安全头文件的第三方HTTP库,要么自己写。
我该如何解决这个问题?如果我从头开始编写自己的库,应该考虑哪些合适的类呢?有相关的样例代码吗?
(这个问题可能与这个问题太相似了,尽管在编写了一些测试代码之后,使用HttpClient
的自定义处理程序的想法也不起作用,因为系统处理程序在响应时首先被调用。)
可以很容易地实现一个基本的HTTP客户端。忽略错误处理并处理Content-Length
(稍后会详细介绍),这段代码应该可以达到目的。
var hostname = new HostName("www.w3.org");
var socket = new StreamSocket();
await socket.ConnectAsync(hostname, "80");
var request = "GET /Protocols/rfc2616/rfc2616-sec4.html HTTP/1.1'r'n" +
"Host: www.w3.org'r'n" +
"'r'n";
var writer = new DataWriter(socket.OutputStream);
writer.WriteString(request);
await writer.StoreAsync();
var reader = new DataReader(socket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
string data = string.Empty;
var cts = new CancellationTokenSource();
bool doneReading = false;
uint bytesToRead = 10240;
while (!doneReading)
{
try
{
cts.CancelAfter(10 * 1000);
await reader.LoadAsync(bytesToRead).AsTask(cts.Token);
data += reader.ReadString(reader.UnconsumedBufferLength);
totalBytesRead += bytesRead;
}
catch (TaskCanceledException)
{
doneReading = true;
}
}
socket.Dispose();
肯定有一些问题需要解决:
- 超时时间为10秒。但这取决于你使用的是哪种连接,也许这没问题?
- 对于这个问题,等待超时是判断服务器是否完成发送数据的错误方法。正如Jon Skeet在使用StreamSocket正确接收数据挂起中提到的,客户端应该从报头中读取
Content-Length
并请求适当的字节数。当然,由于TCP是一个流,这也需要一些工作。
同样,这个解决方案主要适用于Windows Phone 8.1 Silverlight。虽然它也可以在Windows Phone 8.1/Windows Store(即WinRT)应用程序上运行,但在该平台上使用MessageWebSocket
可能更容易。
由于这似乎是一个相当普遍的问题,我为此写了三篇系列文章;第2部分将讨论这种变通方法。同样值得注意的是,错误消息CR must be followed by LF
可能不完全准确——它也可能意味着头中有一个无效字符(包括其中一个头名称中的空格)。