HTTPWebResponse Raw Response,使用Reflection

时间:2011-07-31 04:05:26

标签: c# .net windows sockets httpwebrequest

HTTPWebResponse公开Headers的属性,是否有可能获得原始响应,就像我们使用套接字时一样,Header和Content结合使用 Reflection ,我认为必须有一种方式。

我可以使用socket但是需要很多工作才能使它们可用,比如代理支持,https,进度事件等...列表很长,我强烈建议使用HTTPWebRequest,唯一的问题是我需要带有响应的原始标头,我试图下载的网站发送了一个非常长而奇怪的cookie,它不是由HTTPClRequest,WebClient处理的。 Wordpress博客,无法使用WebClient登录任何wordpress博客,但使用套接字手动cookie处理它完美,可能是WebClient中的一个错误。

1)只需要原始标题即可。

2)还有article link

文章说HTTPWebRequest存在问题,只有一个线程正在下载而其他线程正在等待,如果这是真的那么套接字更好吗?

文章说: 此代码运行良好,但它有一个非常严重的问题,因为WebRequest类函数GetResponse锁定对所有其他进程的访问,WebRequest将检索到的响应告知已关闭,如上一代码中的最后一行。所以我注意到只有一个线程正在下载,而其他线程正在等待GetResponse。为了解决这个严重的问题,我使用Socket实现了我的两个类MyWebRequest和MyWebResponse。

1 个答案:

答案 0 :(得分:8)

有一种获取原始标题的方法:

var rawHeaders = request.GetResponse().Headers.ToString();

通过您提供的网站和请求,我们将其退回:

Pragma: no-cache
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache, must-revalidate, max-age=0
Date: Wed, 03 Aug 2011 12:08:49 GMT
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Set-Cookie: wordpress_test_cookie=WP+Cookie+check;     path=/,wordpress_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/wp-admin,wordpress_sec_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/wp-admin,wordpress_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/wp-content/plugins,wordpress_sec_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/wp-content/plugins,wordpress_logged_in_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpress_logged_in_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpress_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpress_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpress_sec_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpress_sec_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpressuser_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpresspass_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpressuser_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/,wordpresspass_c2d1208bd3bc2294298da94d67693495=+; expires=Tue, 03-Aug-2010 12:08:49 GMT; path=/
Server: Apache
X-Powered-By: PHP/5.2.17
Last-Modified: Wed, 03 Aug 2011 12:08:49 GMT
Content-Type: text/html; charset=UTF-8
X-Cache: MISS from localhost
X-Cache-Lookup: MISS from localhost:3128
Via: 1.0 localhost (squid/3.1.6)
Connection: close

这会解决您的问题吗?

关于套接字而不是WebRequests - 我建议不要使用这种方法。它正在重新发明轮子。

<强>更新

这并没有解决问题,因为上面的标题已经以有损方式解析(有关详细信息,请参阅注释)。经过仔细检查,我得出结论,原始头字节在HttpWebRequest.GetResponse()之后已经丢失。

核心解析在System.Net.WebHeaderCollection.ParseHeaders()System.Net.WebHeaderCollection.ParseHeadersStrict()中完成(取决于System.Net.Configuration.SettingsSectionInternal.Section.UseUnsafeHeaderParsing的值),两种方法都无法记录所需的信息。不久之后,他们操作的缓冲区(System.Net.Connection.m_ReadBuffer)将填充来自线路的新数据。原始标题丢失了。

为了保存原始数据,您需要重新实现System.Net.Connection类,它是ServicePoint的内部和硬引用,它是公共的,但仍然被HttpWebRequest硬引用。总而言之,你必须重新实现整个堆栈。

因此,除非您可以更改网站行为或没有这些Cookie,否则您将需要使用套接字。如果是这样的话,我想表示哀悼。