HTTPWebResponse原始响应,使用反射。

5
HTTPWebResponse暴露了Headers的属性,是否可以使用Reflection获取像使用socket获取的原始响应(Header和Content合并在一起),我认为一定有方法。
我可以使用socket但需要大量工作使它们可用,如代理支持、https、进度事件等...清单很长,我被强烈建议使用HTTPWebRequest,唯一的问题是我需要带响应的原始headers,我正在尝试下载的网站发送了一个非常长而奇怪的cookie,这个cookie不能被HTTPWebRequest、WebClient处理。WordPress博客,使用WebClient无法登录任何WordPress博客,但使用Sockets手动处理cookie可以完美解决,可能是WebClient中的一个bug。 1) 只需要原始headers,那就万事大吉。 2) 而且还有文章链接 文章说HTTPWebRequest存在问题,只有一个线程在下载,而其他线程则被保持等待状态,如果这是真的,那么sockets更好?? 文章说: 这段代码运行良好,但它有一个非常严重的问题,因为WebRequest类函数GetResponse锁定了对所有其他进程的访问,即在前面的代码的最后一行中,WebRequest将检测到检索的响应已关闭。因此,我注意到始终只有一个线程在下载,而其他线程则在等待GetResponse。为了解决这个严重的问题,我使用Socket实现了我的两个类MyWebRequest和MyWebResponse。
1个回答

9

有一种方法可以获取原始头信息:

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

这能解决你的问题吗?

关于使用套接字(Socket)而不是Web请求 - 我建议反对这种方法,这是重复造轮子。

更新

这并不能解决问题,因为上述标头已经以有损方式进行了解析(详见注释)。经过仔细检查,我得出结论,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进行硬引用,ServicePoint是公共类但仍由HttpWebRequest进行硬引用。换句话说,您必须重新实现整个堆栈。

因此,除非您可以更改网站行为或无法使用这些Cookie,否则您将需要使用Socket。如果是这种情况,我想向您表示慰问。


wordpress_c2d1208bd3bc2294298da94d67693495=+;看这个,这不是一个完整的cookie,它被破坏了,现在用sockets尝试同样的操作,你将得到完整的cookie。 - Milan Solanki
好的,现在我明白了。非常奇怪(以下是由Firefox解释的单个cookie):wordpress_test_cookie=WP+Cookie+check; path=/ - Jacek Gorgoń
同时,"wordpress_c2d1208bd3bc2294298da94d67693495=+;" 这部分实际上类似于 "wordpress_6e7750f6a474de23330d1b7f0e9990c6=admin%7C1301039544%7C16d39b9f49cf062500d50471df7320e9;" 但被拆成了两半。 - Milan Solanki
在一个名为useUnsafeHeaderParsing的过程中涉及到一个内部类中的私有字段,其默认设置为false。不幸的是,将它设置为true并不能起到帮助作用。深入挖掘... - Jacek Gorgoń
我也遇到了这个问题,特别是对于重复的标头(例如Set-Cookie)或任何包含嵌入逗号的内容。他们存储了字符串块,然后实际上在GetValues上拆分逗号! - Thomas S. Trias

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