如何在HttpWebRequest中设置一个自定义的主机头?我知道通常这个类不允许这样做,但是有没有办法使用反射或类似的东西,而不需要我用TCPClient发送整个数据包?
axzmvihb1#
有一种迂回的方法可以做到这一点,如下所述:http://blogs.msdn.com/feroze_daud/archive/2005/03/31/404328.aspx但是,框架的下一个版本(.NET Framework 4.0)将使这一点变得更容易。http://blogs.msdn.com/ncl/archive/2009/07/20/new-ncl-features-in-net-4-0-beta-2.aspx希望这对你有帮助。
fquxozlt2#
招魂术。对于仍在使用.NET 2.0的用户如果你知道怎么做的话,这实际上是很容易的。问题是,你不能设置主机头,因为框架不允许你在运行时更改值。(.net framework 4.0+允许你在httpwebrequest中重写主机)。下一个尝试是用反射来设置header,这样你就可以改变header的值,但是在运行时,它会用url的主机部分覆盖这个值,这意味着反射不会给你带来任何东西。如果dns-name不存在(坦率地说,这是您首先要执行此操作的唯一情况),则无法设置它,因为.NET无法解析它,并且您无法覆盖.NET DNS解析器。但你可以做的是设置一个与目标服务器IP完全相同的Web代理。因此,如果您的服务器IP是28.14.88.71:
public class myweb : System.Net.WebClient { protected override System.Net.WebRequest GetWebRequest(System.Uri address) { System.Net.WebRequest request = (System.Net.WebRequest)base.GetWebRequest(address); //string host = "redmine.nonexistantdomain.com"; //request.Headers.GetType().InvokeMember("ChangeInternal", // System.Reflection.BindingFlags.NonPublic | // System.Reflection.BindingFlags.Instance | // System.Reflection.BindingFlags.InvokeMethod, null, // request.Headers, new object[] { "Host", host } //); //server IP and port request.Proxy = new System.Net.WebProxy("http://28.14.88.71:80"); // .NET 4.0 only System.Net.HttpWebRequest foo = (System.Net.HttpWebRequest)request; //foo.Host = host; // The below reflection-based operation is not necessary, // if the server speaks HTTP 1.1 correctly // and the firewall doesn't interfere // https://yoursunny.com/t/2009/HttpWebRequest-IP/ System.Reflection.FieldInfo horribleProxyServicePoint = (typeof(System.Net.ServicePoint)) .GetField("m_ProxyServicePoint", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); horribleProxyServicePoint.SetValue(foo.ServicePoint, false); return foo; return request; } }
瞧现在
myweb wc = new myweb(); string str = wc.DownloadString("http://redmine.non-existant-domain.com");
并且如果28.14.88.71是一个基于虚拟名称的主机(基于http-host-header)的Web服务器,则返回正确的页面。
iezvtpos3#
你可以使用这个黑客,专为解决这个问题在.Net 3.5 .
using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Reflection; namespace ConsoleApplication6 { class Program { static void Main(string[] args) { HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://198.252.206.16"); FieldInfo headersFieldInfo = request.GetType().GetField("_HttpRequestHeaders", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetField); ClusteredHeaderCollection headers = new ClusteredHeaderCollection("stackoverflow.com"); headersFieldInfo.SetValue(request, headers); request.Proxy = null; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StreamReader sr = new StreamReader(response.GetResponseStream()); string result = sr.ReadToEnd(); Console.WriteLine(result); Console.ReadLine(); } public class ClusteredHeaderCollection : WebHeaderCollection { public bool HostHeaderValueReplaced { get;private set; } public string ClusterUrl { get; private set; } public ClusteredHeaderCollection(string commonClusterUrl) : base() { if (string.IsNullOrEmpty("commonClusterUrl")) throw new ArgumentNullException("commonClusterUrl"); this.ClusterUrl = commonClusterUrl; } public override string ToString() { this["Host"] = this.ClusterUrl; string tmp = base.ToString(); this.HostHeaderValueReplaced = true; return tmp; } } } }
xzv2uavs4#
WebClient允许这样做。
var client = new WebClient(); client.Headers.Add( "Host", WebHeader );
我不能告诉你为什么。文档清楚地说明主机是一个系统头文件。
e7arh2l65#
您可以使用代理,请参阅我答复:在C#中请求网页欺骗主机
5条答案
按热度按时间axzmvihb1#
有一种迂回的方法可以做到这一点,如下所述:
http://blogs.msdn.com/feroze_daud/archive/2005/03/31/404328.aspx
但是,框架的下一个版本(.NET Framework 4.0)将使这一点变得更容易。
http://blogs.msdn.com/ncl/archive/2009/07/20/new-ncl-features-in-net-4-0-beta-2.aspx
希望这对你有帮助。
fquxozlt2#
招魂术。
对于仍在使用.NET 2.0的用户
如果你知道怎么做的话,这实际上是很容易的。
问题是,你不能设置主机头,因为框架不允许你在运行时更改值。(.net framework 4.0+允许你在httpwebrequest中重写主机)。
下一个尝试是用反射来设置header,这样你就可以改变header的值,但是在运行时,它会用url的主机部分覆盖这个值,这意味着反射不会给你带来任何东西。
如果dns-name不存在(坦率地说,这是您首先要执行此操作的唯一情况),则无法设置它,因为.NET无法解析它,并且您无法覆盖.NET DNS解析器。
但你可以做的是设置一个与目标服务器IP完全相同的Web代理。
因此,如果您的服务器IP是28.14.88.71:
瞧现在
并且如果28.14.88.71是一个基于虚拟名称的主机(基于http-host-header)的Web服务器,则返回正确的页面。
iezvtpos3#
你可以使用这个黑客,专为解决这个问题在.Net 3.5 .
xzv2uavs4#
WebClient允许这样做。
我不能告诉你为什么。文档清楚地说明主机是一个系统头文件。
e7arh2l65#
您可以使用代理,请参阅我答复:在C#中请求网页欺骗主机