Request Web Page in c# spoofing the Host

Muszę utworzyć prośbę o stronę internetową dostarczoną do naszych stron internetowych, ale muszę być w stanie ustawić informacje nagłówka hosta. Próbowałem to za pomocą HttpWebRequest, ale informacje nagłówka jest tylko do odczytu(lub przynajmniej część hosta jest). Muszę to zrobić, ponieważ chcemy wykonać wstępne żądanie dla strony, zanim użytkownik będzie mógł. Mamy 10 serwerów WWW, które są zrównoważone obciążeniem, więc musimy zażądać pliku z każdego z serwerów internetowych.

Próbowałem "po": {]}

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.5/filename.htm");
request.Headers.Set("Host", "www.mywebsite.com");
WebResponse response = request.GetResponse();

Oczywiście to nie działa, ponieważ nie mogę zaktualizować nagłówka i nie wiem, czy to rzeczywiście jest właściwy sposób, aby to zrobić.

Author: bignose, 2008-12-11

9 answers

Chociaż jest to bardzo późna odpowiedź, może ktoś z niej skorzysta

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri("http://192.168.1.1"));
request.Headers.GetType().InvokeMember("ChangeInternal", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, request.Headers, new object[] {"Host","www.mysite.com"});

Reflection is your friend:)

 10
Author: L.B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-26 19:33:06

Udało mi się znaleźć dłuższą trasę za pomocą gniazd. Znalazłem odpowiedź na stronie MSDN dla IPEndPoint:

string getString = "GET /path/mypage.htm HTTP/1.1\r\nHost: www.mysite.mobi\r\nConnection: Close\r\n\r\n";
Encoding ASCII = Encoding.ASCII;
Byte[] byteGetString = ASCII.GetBytes(getString);
Byte[] receiveByte = new Byte[256];
Socket socket = null;
String strPage = null;
try
{
    IPEndPoint ip = new IPEndPoint(IPAddress.Parse("10.23.1.93"), 80);
    socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    socket.Connect(ip);
}
catch (SocketException ex)
{
    Console.WriteLine("Source:" + ex.Source);
    Console.WriteLine("Message:" + ex.Message);
}
socket.Send(byteGetString, byteGetString.Length, 0);
Int32 bytes = socket.Receive(receiveByte, receiveByte.Length, 0);
strPage = strPage + ASCII.GetString(receiveByte, 0, bytes);

while (bytes > 0)
{
    bytes = socket.Receive(receiveByte, receiveByte.Length, 0);
    strPage = strPage + ASCII.GetString(receiveByte, 0, bytes);
}
socket.Close();
 9
Author: Xetius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-11 13:18:19

Miałem problem, w którym adres URL dns, którego użyłem, miał kilka różnych adresów IP, chciałem wywołać każdy adres osobno, używając tej samej nazwy dns w hoście - rozwiązaniem jest użycie proxy:

string retVal = "";
            // Can't change the 'Host' header property because .NET protects it
            // HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            // request.Headers.Set(HttpRequestHeader.Host, DEPLOYER_HOST);
            // so we must use a workaround
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Proxy = new WebProxy(ip);
            using (WebResponse response = request.GetResponse())
            {
                using (TextReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                        retVal += line;
                }
            }
            return retVal;

Nagłówek hosta jest automatycznie ustawiany z adresu url przez. Net, A " ip " zawiera rzeczywisty adres serwera www, z którym chcesz się skontaktować (Możesz również użyć nazwy dns)

 4
Author: thedrs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-12 11:02:09

Wiem, że to stare, ale natknąłem się na ten sam problem i znalazłem lepsze rozwiązanie tego problemu, używając gniazd lub odbicia...

To, co zrobiłem, to stworzenie nowej klasy, która działa z WebHeaderCollection i omija walidację tego, co w niej wsadzasz:

public class MyHeaderCollection:WebHeaderCollection
{
    public new void Set(string name, string value)
    {
        AddWithoutValidate(name, value);
    }
    //or
    public new string this[string name]
    {
        get { return base[name]; }
        set { AddWithoutValidate(name, value); }
    }
}

A oto jak go używasz:

    var http = WebRequest.Create("http://example.com/");
    var headers = new MyHeaderCollection();
    http.Headers = headers;

    //Now you can add/override anything you like without validation:
    headers.Set("Host", http.RequestUri.Host);
    //or
    headers["Host"] = http.RequestUri.Host;

Mam nadzieję, że to pomoże każdemu, kto tego szuka!

 2
Author: Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-15 08:21:36

Wiem, że to stare pytanie, ale w dzisiejszych czasach możesz to zrobić.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.5/filename.htm");
request.Host = "www.mywebstite.com";
WebResponse response = request.GetResponse();
 1
Author: Will Munn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-18 08:18:51

Nagłówek "Host" jest chroniony i nie może być modyfikowany programowo. Przypuszczam, że aby obejść to rozwiązanie, możesz spróbować powiązać poprzez odbicie z prywatną właściwością" InnerCollection "obiektu WebRequest i wywołać na nim metodę" Set " ar "Add", aby zmodyfikować nagłówek hosta. Nie próbowałem tego, ale z szybkiego spojrzenia na kod źródłowy w Reflector, myślę, że łatwo to osiągnąć. Ale tak, powiązanie z prywatnymi właściwościami obiektów framework nie jest najlepszym sposobem na osiągnięcie rzeczy. :) Używaj tylko jeśli musisz.

Edit: albo jak inny facet wspomina w podlinkowanym pytaniu, po prostu otwórz gniazdo i zrób szybkie "GET" ręcznie. Powinno być bezmyślne, jeśli nie musisz majstrować innymi rzeczami, takimi jak pliki cookie lub cokolwiek innego, co zapewnia HttpWebRequest.

 0
Author: Strelok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-11 11:58:01

Dobra, trochę badań wychodzi na to:

Https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=384456

Wydaje się, że MS może coś z tym zrobić w pewnym momencie.

 0
Author: annakata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-27 14:14:26

Możesz użyć mojego rozwiązania tego problemu, napisano tutaj:

Jak ustawić niestandardowy nagłówek "Host" w HttpWebRequest?

To pomoże Ci edytować nagłówek hosta i uniknąć używania proxy i bezpośrednich żądań gniazd.

 0
Author: user2225191,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:25

Nekromancja.
Dla tych, którzy nadal korzystają z. 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ż framework nie pozwala na zmianę wartości w czasie wykonywania. (. NET framework 4.0 + pozwoli zastąpić hosta w httpwebrequest).

Następną próbą będzie ustawienie nagłówka z odbiciem-jak pokazano w top upvoted odpowiedzi tutaj - aby obejść go, co pozwoli Ci zmienić wartość nagłówka. Ale w czasie wykonywania, będzie zastąp tę wartość częścią hostaurl , co oznacza, że odbicie nic Ci nie przyniesie, dlatego nie rozumiem, dlaczego ludzie trzymająw górze głosując na to.

Jeśli nazwa dns nie istnieje, co jest szczerze mówiąc jedynym przypadkiem, w którym chcesz to zrobić, nie możesz jej ustawić, ponieważ. NET nie może jej rozwiązać i nie możesz nadpisać resolvera. NET DNS.

Ale co możesz zrobić, to ustawić webproxy z dokładnie taki sam adres IP jak serwer docelowy.

Więc jeśli IP Twojego serwera to 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
    }


    }

I voila, teraz

myweb wc = new myweb();
string str = wc.DownloadString("http://redmine.netexistantdomain.com");

I otrzymasz poprawną stronę z powrotem, jeśli 28.14.88.71 jest serwerem WWW z wirtualnym hostingiem opartym na nazwie (opartym na http-host-header).

Teraz masz poprawną odpowiedź na oryginalne pytanie, zarówno dla WebRequest, jak i WebClient. Myślę, że używanie niestandardowych gniazd do tego byłoby złym podejściem, szczególnie gdy powinno być używane SSL, a gdy rzeczywisty rozwiązanie jest takie proste...

 0
Author: Stefan Steiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-21 08:09:05