.net 如何设置自定义";主持人;HttpWebRequest中的标头?
如何在HttpWebRequest中设置自定义主机头?我知道,通常这个类不允许您这样做,但是否可以使用反射或类似的方法,而不需要我使用TCPClient发送整个数据包?有一种迂回的方法可以做到这一点,如下所述: 但是,该框架的下一个版本(.NET framework 4.0)将使其更加容易.net 如何设置自定义";主持人;HttpWebRequest中的标头?,.net,http,reflection,httpwebrequest,host,.net,Http,Reflection,Httpwebrequest,Host,如何在HttpWebRequest中设置自定义主机头?我知道,通常这个类不允许您这样做,但是否可以使用反射或类似的方法,而不需要我使用TCPClient发送整个数据包?有一种迂回的方法可以做到这一点,如下所述: 但是,该框架的下一个版本(.NET framework 4.0)将使其更加容易 希望这有帮助。您可以使用代理,请参阅我的答案: 您可以使用此黑客,它是为解决.NET3.5中的此问题而设计的 using System; using System.Collections.Generic;
希望这有帮助。您可以使用代理,请参阅我的答案:
您可以使用此黑客,它是为解决.NET3.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);
CusteredHeaderCollection WssHeaders = new CusteredHeaderCollection("stackoverflow.com");
headersFieldInfo.SetValue(request, WssHeaders);
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 CusteredHeaderCollection : WebHeaderCollection
{
public bool HostHeaderValueReplaced { get;private set; }
public string ClusterUrl { get; private set; }
public CusteredHeaderCollection(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;
}
}
}
}
WebClient允许它
var client = new WebClient();
client.Headers.Add( "Host", WebHeader );
我不能告诉你为什么。文档清楚地说明了主机是一个系统头。死灵术对于仍在.NET 2.0上的用户
如果你知道怎么做的话,这其实很容易 问题是,您无法设置主机头,因为框架不允许您在运行时更改该值。(.net framework 4.0+将允许您在httpwebrequest中重写主机) 下一次尝试将使用反射设置标题,以绕过它,这将允许您更改标题值。但在运行时,它将用url的主机部分覆盖该值,这意味着反射不会给您带来任何结果 如果dns名称不存在(坦率地说,这是您首先要执行此操作的唯一情况),则无法设置它,因为.NET无法解析它,并且无法覆盖.NET dns解析程序 但是,您可以做的是使用与目标服务器完全相同的IP设置webproxy 因此,如果您的服务器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主机头)的Web服务器,则返回正确的页面。您希望在头中更改什么?由于大多数头参数可以由属性间接修改,为什么需要自己设置“主机”头。如果您向
www.google.com
发出请求,它只会变成主机头。@Yannick host和其他保留参数不能。我已经看到了该页面,尽管该解决方案中存在很多问题,但除此之外,它是一个非常肮脏的解决方案:)这是因为它不起作用-异常主机头不能直接更改。不起作用。ArgumentException:必须使用appropiate属性修改此标题。它确实有效。正如我所说,在生产中运行。System.Net.WebClient。针对.NET2.0的目标3.5Nice。显然,如果您实际需要使用代理服务器,这将不起作用;)只需升级到.NET 4.5即可-WebRequest和WebClient都不推荐使用。