如何在Windows Phone/Store应用程序中接受“不安全”的HTTP响应头?

3
最近,一个使用HttpClient访问第三方REST API的Windows Phone 8.1 Silverlight应用程序中的一些代码停止工作。我收到了以下错误信息:

'mscorlib.ni.dll'中发生了类型为'System.Exception'的一次性异常

附加信息:灾难性故障(来自HRESULT的异常:0x8000FFFF(E_UNEXPECTED))

在Windows Phone(Silverlight)和商店(RT)应用程序中尝试后,我在WPF中重写了相同的代码,并最终获得了有用的错误消息:

服务器提交了协议违规行为。 Section = ResponseHeader Detail = CR必须由LF跟随"

此问题还有一个很好的深入博客文章
Microsoft已经表示他们不会修复/允许这个问题,所以我只能被迫寻找第三方HTTP库来允许不安全的标头或者自己编写代码。
如何解决这个问题?如果我从头开始编写自己的库,应该考虑哪些适当的类?是否有相关的示例代码可用?
(这个问题可能与这个太相似了,尽管在编写一些测试代码后,使用带有HttpClient的自定义处理程序的想法也不起作用,因为系统处理程序首先被调用。)

1
这是一个很好的问题,但是由于当前标题和“是否存在这样的库”可能会被关闭为“推荐或查找库、工具等”的离题问题。也许你可以稍微改变措辞? - Eugene Podskal
向“第三方”报告错误? - Mikko Viitala
@MikkoViitala 我一个月前就已经反馈了,但他们仍未修复。请查看MSDN链接,指出使用GoPro(和其他数据)也会出现同样的问题。我认为我们需要一个客户端解决方案来解决这个问题。 - Jedidja
@EugenePodskal 感谢您的建议;我已经更新了我的问题,希望现在更加可接受。如果您有任何重新表述的建议,请告诉我... - Jedidja
1个回答

0
原来你可以相当容易地实现一个基本的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在Correctly receiving data using StreamSocket hangs中提到的那样,客户端应该从头文件中读取Content-Length并请求相应数量的字节。当然,由于TCP是一个流协议,这也需要一些工作。

此外,此解决方案主要适用于Windows Phone 8.1 Silverlight。虽然它也可以在Windows Phone 8.1 / Windows Store(即WinRT)应用程序上运行,但在该平台上使用MessageWebSocket可能更容易。

我写了一个三部分的系列文章,因为这似乎是一个相当普遍的问题;这个解决方法在第二部分中讨论。值得注意的是,错误信息CR must be followed by LF可能不完全准确--它也可能意味着头部有一个无效字符(包括一个头部名称中的空格)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接