1

我们正在使用 C# 为我们的应用程序构建一个全面的集成测试框架,该框架存在于 HTTP 之上,使用 IIS7 来托管我们的应用程序。

作为我们集成测试的一部分,我们希望测试传入请求,当客户端发送的 HTTP 标头指示比它实际传输的更大的正文大小时,会发生 EndOfStreamExceptions(“无法读取超出流的末尾”)作为一部分身体。我们想针对这种情况测试我们的错误恢复代码,所以我们需要模拟这些类型的请求。

我正在寻找一个基于 .NET Fx 的套接字库或自定义 HttpWebRequest 替代品,它专门允许开发人员模拟此类条件以添加到我们的集成测试套件中。有谁知道任何这样的图书馆?可编写脚本的解决方案也可以。

4

4 回答 4

4

在调用 GetRequestStream(或 BeginGetRequestStream)之前设置 ContentLength 属性,然后向该流写入更少的字节。如果您在获得请求流后尝试设置 ContentLength ,则会抛出异常。如果您不设置 ContentLength,HttpWebRequest 将缓冲标头,直到流关闭,以便它可以适当地设置 ContentLength(或者,您可以使用 SendChunked,但这对您不起作用)。如果您想最大程度地控制它,请手动创建一个或两个畸形请求,然后打开一个到服务器上端口 80 的套接字并将请求写入 TCP 流,然后读取响应并检查连接是否已关闭.

然而:我不认为这个测试是一个好主意。这是问题所在:

客户端向服务器发送请求。它声称内容将是 100 字节。然后它发送 90 个字节,然后停止发送,使连接保持打开状态。服务器读取 90 个字节,然后等待其余的,因为客户端说将发送 100 个字节。现在,客户端发送第二个请求。服务器将如何处理新请求的前 10 个字节?

答案是服务器会假设这些字节是前一个请求的一部分并将它们视为这样,然后在开始后 10 个字节开始读取“新”请求,这显然会导致格式错误的标头。服务器不喜欢这样,所以它会发送一个 4xx 错误,然后它会关闭连接。它关闭连接的原因是因为它现在无法知道发送给它的数据意味着什么,也无法恢复。此外,连接的关闭不会是优雅的,它会很突然,并且另一端的 HttpWebRequest 正在提交第二个请求(或者第三个或第四个,如果他们排队)将抛出一个 WebException 说底层连接已关闭,让您猜测原因。

同样的行为是导致连接以 Expect 100-continue 标头关闭的原因,并且服务器返回 100-continue 后跟 4xx,例如当需要 Auth 时。即使它拒绝了请求,它仍然必须假设下一个字节是同一个请求的一部分,因为它已经承诺通过发送 100-continue 来接收这些字节。如果它不会为该请求提供服务,或者如果客户端想要取消请求并提交一个新请求(可能带有身份验证凭据),那么它必须关闭连接并打开一个新请求。

最后,使用 TCP 从网络流中测试 EndOfStreamException 对我来说根本没有任何意义。TCP 不会标记流的“结束”,它只是在将数据写入套接字时继续发送数据。它没有“EOF”,也无法检测数据是否已全部传输,除非您知道预期有多少数据。除非连接关闭,否则 TCP 的流实际上并没有“结束”,在这种情况下,您将获得 WebException 或 SocketException,具体取决于您在堆栈中的操作位置。协议中的任何传输错误都在winsock中处理。如果不再发送数据,则连接的一端最终将向另一端发送保持活动状态,以确保连接实际上仍处于打开状态,并且一台主机不会直接丢弃它。如果 keepalive 超时,连接将被关闭,并且您下次尝试从中读取时可能会收到 WebException。鉴于所有这些是如何工作的,我只是看不出你将如何从这个测试中获得任何价值。您最好只发送格式错误的请求并确保相应地处理错误并将适当的 4xx 消息发送回客户端并正确关闭连接。

于 2009-08-28T09:18:36.980 回答
0

我不知道有任何这样的库,但在我看来,如果那是您正在编码的地方,那么在接收端它会非常简单。

只需检索整个 WebRequest,尽可能多地或尽可能少地截断,然后继续转发。您可能需要在此过程中制作 WebRequest 的新副本,而不是就地截断,但它仍然应该是直截了当的。

于 2009-08-25T16:29:00.903 回答
0

您不能HttpWebRequest.ContentLength将客户端上的属性设置为比数据的实际大小更小或更大的值吗?

于 2009-08-28T08:41:47.460 回答
0

如果您想模拟任何违反 HTTP 协议的事情,那么您将不得不编写自己的代码来执行此操作。HttpWebRequest 不允许你做这样的事情。

于 2009-09-13T20:29:27.123 回答