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

时间:2014-08-08 18:09:47

标签: c# windows-phone-8 windows-store-apps windows-phone-8.1

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

  

mscorlib.ni.dll

中出现'System.Exception'类型的第一次机会异常      

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

在Windows Phone(Silverlight)和Store(RT)应用程序中尝试此操作后,我在WPF中重写了相同的代码,最后得到了一条有用的错误消息:

  

服务器提交了协议违规。 Section = ResponseHeader Detail = CR必须后跟LF“

此问题还有great in-depth blog post

微软已声明他们will not fix/allow this所以我要么被迫找到第三方HTTP库,它会允许不安全的标头或自己编写。

我该如何解决这个问题?如果我从头开始编写自己的库,那么适当的类需要考虑什么?是否有相关的示例代码?

(这个问题可能与this one太相似了,尽管在编写了一些测试代码之后,自HttpClient使用自定义处理程序的想法也不起作用,因为响应system handler is called first 。)

1 个答案:

答案 0 :(得分: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 {s}在Correctly receiving data using StreamSocket hangs中提到的那样,客户端应该从头部读取Content-Length并请求相应的字节数。当然,自TCP is a stream起,这也需要一些工作。

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

我写了一篇由三部分组成的系列文章,因为它似乎是一个相当普遍的问题;我在part two中讨论了这种解决方法。另外值得注意的是错误消息CR must be followed by LF may not be completely accurate - 它也可能意味着标题中存在无效字符(包括其中一个标题名称中的空格)。