死灵术。
对于仍在使用 .NET 2.0 的用户
其实很简单,如果你知道怎么做的话。
问题是,您不能设置主机标头,因为框架不允许您在运行时更改值。 (.net framework 4.0+ 将允许您在 httpwebrequest 中覆盖主机)。
下一次尝试将设置带有反射的标题 - 如此处最受好评的答案所示 - 绕过它,这将让您更改标题值。但是在运行时,它会用url的host部分覆盖这个值,这意味着反射不会给你带来任何东西,这就是为什么我不 了解人们为什么一直支持投票。
如果 dns 名称不存在,坦率地说,这是您首先要执行此操作的唯一情况,您无法设置它,因为 .NET 无法解析它,并且您无法覆盖 .NET DNS 解析器。
但是您可以做的是设置一个与目标服务器具有完全相同 IP 的网络代理。
所以,如果你的服务器 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; // or return request; if you don't neet this
}
}
瞧,现在
myweb wc = new myweb();
string str = wc.DownloadString("http://redmine.netexistantdomain.com");
如果 28.14.88.71 是具有基于虚拟名称的托管(基于 http-host-header)的网络服务器,那么您会返回正确的页面。
现在您对于 WebRequest 和 WebClient 都得到了原始问题的正确答案。我认为使用自定义套接字来执行此操作是错误的方法,尤其是在应该使用 SSL 时,以及当实际解决方案如此简单时......