Jak ustawić niestandardowy nagłówek hosta w HttpWebRequest? Wiem, że normalnie ta klasa nie pozwala ci na to, ale czy mimo to używasz odbicia lub czegoś podobnego bez potrzeby wysyłania całego pakietu za pomocą TCPClient?Jak ustawić niestandardowy nagłówek "Host" w HttpWebRequest?
Odpowiedz
Jest rondo sposobem, aby to zrobić, jak to opisano tutaj:
http://blogs.msdn.com/feroze_daud/archive/2005/03/31/404328.aspx
Jednak kolejna wersja ram (.NET Framework 4.0) będzie łatwiej.
http://blogs.msdn.com/ncl/archive/2009/07/20/new-ncl-features-in-net-4-0-beta-2.aspx
Nadzieja to pomaga.
Widziałem tę stronę, chociaż istnieje wiele problemów w tym obejściu, oprócz tego, że jest to naprawdę brudne obejście :) –
Wstyd Nie używam .NET 4, który wygląda dobrze. –
można użyć serwera proxy, zobacz moją odpowiedź na: Request Web Page in c# spoofing the Host
Można użyć tego hack, przeznaczonego dla rozwiązania tego problemu w .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);
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 na to pozwala.
var client = new WebClient();
client.Headers.Add("Host", WebHeader);
Nie mogłem ci powiedzieć dlaczego. Dokumentacja wyraźnie stwierdza, że Host jest nagłówkiem systemu.
Nekromowanie.
Dla tych, którzy wciąż na .NET 2.0
Jest to w rzeczywistości dość łatwe, jeśli wiesz jak.
Problem polega na tym, że nie można ustawić nagłówka hosta, ponieważ struktura nie pozwala na zmianę wartości w czasie wykonywania. (.net framework 4.0+ pozwoli ci przesłonić hosta w httpwebrequest).
Następną próbą będzie ustawienie nagłówka z odbiciem, aby obejść go, co pozwoli ci zmienić wartość nagłówka. Ale w czasie działania nadpisze tę wartość z częścią hosta adresu URL, co oznacza, że refleksja nie przyniesie nic.
Jeśli nazwa dns nie istnieje, co jest szczerym jedynym przypadkiem, w którym chcesz to zrobić w pierwszej kolejności, nie możesz jej ustawić, ponieważ .NET nie może go rozwiązać, i nie można przesłonić resolwera .NET DNS.
Ale możesz ustawić webproxy z tym samym adresem IP co serwer docelowy.
Dlatego, jeśli IP serwera jest 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;
}
}
i voila, teraz
myweb wc = new myweb();
string str = wc.DownloadString("http://redmine.non-existant-domain.com");
i masz odpowiednią stronę z powrotem, jeśli 28.14.88.71 jest serwer WWW z wirtualnym hosting oparty na nazwach (oparty na nagłówku hosta http).
Przyjemnie, dla .NET 2.0. Oczywiście to nie zadziała, jeśli rzeczywiście będziesz potrzebować serwera proxy;) Wystarczy dokonać aktualizacji do .NET 4.5 - WebRequest i WebClient są i tak przestarzałe. – User1
Co dokładnie chcesz zmienić w nagłówku? Ponieważ większość parametrów nagłówka może być pośrednio modyfikowana przez właściwości –
. Dlaczego musisz ustawić nagłówek "Host" samodzielnie. Jeśli poprosisz o "www.google.com", stanie się on po prostu nagłówkiem hosta. –
@Nickick Host i inne zastrzeżone parametry nie mogą. –