Переопределить IP в HTTP-запросе

Ищете способ выдать HTTPwebrequest, или использовать элемент управления браузером, или winhttp, чтобы сделать запрос к URL-адресу, но переопределить IP-адрес, к которому он подключается, из поиска DNS на определенный.

Попытка сделать что-то похожее на файл HOSTS, но программно без изменения этого файла. Это может быть С# или С+

Зачем мне это нужно, хост, на который я отправляю запрос, имеет несколько IP-адресов, и их доменные серверы выполняют балансировку нагрузки по разным IP-адресам. Попытка принудительно отправить запрос на определенный IP-адрес, но мне нужно, чтобы хост в http-запросе оставался исходным хостом. Мне это нужно программно, потому что изменение файла хоста каждый раз, когда мне нужно запустить этот тест, занимает слишком много времени.


person httpresearcher    schedule 09.01.2010    source источник


Ответы (4)


Все, что вам нужно было сделать, это:

var request = (HttpWebRequest) WebRequest.Create("http://192.168.1.1");
request.Host = "news.bbc.co.uk";
person Kayode Leonard    schedule 10.12.2011
comment
+1 Кажется, свойство Host было добавлено в .NET 4. - person Alex Jasmin; 04.08.2012
comment
Если вы сделаете это с отражением в версии до 4.0, это не сработает, потому что он перезапишет заголовок хоста при отправке запроса. - person Stefan Steiger; 19.12.2016

Если я правильно понимаю, вам нужно сделать http-запрос на веб-сервер, используя виртуальные хосты, но DNS еще не настроен, поэтому вам нужно указать IP-адрес в URL-адресе, но отправить что-то еще в Host: заголовок.

Если это так, вы можете сделать это.

В C# с использованием WebProxy:

См. ответ Кайоде Леонарда для .NET 4 и выше.

Вот код, который я бы использовал, если бы мой сервер работал на 67.223.227.171:8888, но мне нужно иметь www.example.com в заголовке Host:.

System.Net.WebRequest r = System.Net.WebRequest.Create("http://www.example.com");
r.Proxy = new WebProxy("http://67.223.227.171:8888");

См. эту ссылку.

В C++ с использованием WinHttp:

Используя WinHttp, вы можете просто установить заголовок Host: с помощью WinHttpAddRequestHeaders.

Итак, еще раз, если мой сервер работает на 67.223.227.171:8888, но мне нужно иметь www.example.com в заголовке Host::

#include <windows.h>
#include <winhttp.h>
#include <assert.h>

int main() {
  HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", 
                                    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                    WINHTTP_NO_PROXY_NAME, 
                                    WINHTTP_NO_PROXY_BYPASS, 0);

  assert(hSession != NULL);


  // Use WinHttpConnect to specify an HTTP server.
  HINTERNET hConnect = WinHttpConnect( hSession,
                             L"67.223.227.171",
                             8888,
                             0 );

  assert(hConnect != NULL);

  // Open and Send a Request Header.
  HINTERNET  hRequest = WinHttpOpenRequest( hConnect,
                                 L"GET", 
                                 L"/downloads/samples/internet/winhttp/retoptions/redirect.asp", 
                                 NULL,
                                 WINHTTP_NO_REFERER,
                                 WINHTTP_DEFAULT_ACCEPT_TYPES,
                                 0 );

    assert(hRequest != NULL);

   BOOL httpResult = WinHttpAddRequestHeaders(
                                  hRequest,
                                  L"Host: www.example.com",
                                  -1L,
                                  0);

   assert(httpResult);

  httpResult = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 
                                   0,
                                   WINHTTP_NO_REQUEST_DATA,
                                   0,
                                   0,
                                   0 );

  assert(httpResult);

  httpResult = WinHttpReceiveResponse( hRequest, NULL );

  assert(httpResult);
}

Отредактировано: имя класса — WebProxy. Добавлен пример кода C#. Добавлен пример кода C++.

person Alex Jasmin    schedule 09.01.2010
comment
@Alexandre - только что попробовал - это выглядело как довольно новый подход (обратите внимание, что в статье он исправляет использование CustomWebProxy и говорит, что это должен быть просто WebProxy). Однако, похоже, это не работает — запрос по-прежнему имеет исходный заголовок хоста. Я могу ошибаться - вы не можете легко использовать Fiddler для отладки, поскольку Fiddler работает, устанавливая прокси-сервер (который специально отменяет это решение). Однако, используя сниффер пакетов tcp, похоже, он не работает. Позор действительно. - person Rob Levine; 09.01.2010
comment
Я отредактировал свой пост. Это чем-нибудь поможет? Я, кажется, получил правильный заголовок здесь. - person Alex Jasmin; 09.01.2010
comment
+1 - у меня была вторая попытка - и я думаю, что вы правы - похоже, это работает. Кроме того, хорошее место для отладки Fiddler путем установки прокси-сервера в качестве прокси-сервера Fiddler. Очевидно, но я просто пропустил это :) Очень ловкий трюк. - person Rob Levine; 09.01.2010
comment
есть что-то подобное для WINHTTP? - person httpresearcher; 09.01.2010
comment
@httpresearcher выглядит так. Я добавил еще один образец. - person Alex Jasmin; 09.01.2010

[Примечание в дополнение к ответу Кайоде Леонарда: свойство Host было добавлено к запросу в .Net 4.0, что сделало этот ответ устаревшим]

Я думаю, вы говорите, что хотите иметь возможность переопределить IP-адрес для данного хоста без изменения заголовка хоста.

Например, news.bbc.co.uk сопоставляется с IP-адресом 212.58.226.139, но вы хотите иметь возможность сопоставить его с другим IP-адресом, по-прежнему представляя тот же news.bbc.co. uk HTTP-заголовок «Host» на переопределенный адрес. Это то, чего вы добьетесь, переопределив файл HOSTS, как вы говорите, что немного отличается от ответа Джейсона, поскольку он не будет представлять исходный http-заголовок «Host».

Я не верю, что вы можете сделать это легко (хотя я собираюсь поэкспериментировать, чтобы выяснить это!). Конечно, вы не можете сделать следующее:

var request = (HttpWebRequest) WebRequest.Create("http://192.168.1.1");
request.Headers["Host"] = "news.bbc.co.uk";

так как это приведет к ошибке с сообщением о том, что вы не можете изменить заголовок «Host».

Вы, вероятно, можете это сделать, если хотите спуститься на уровень ниже HttpWebRequest и работать на более высоком уровне TCP, но я не уверен, как бы вы подошли к этому, не опускаясь до этого уровня.

[Изменить]: поэкспериментировав с различными подходами к переопределению HttpWebRequest и WebHeaderCollection, я почти уверен, что это невозможно сделать таким образом. Однако ответ Александра Жасмина кажется решением.

person Rob Levine    schedule 09.01.2010

Я добавляю ответ, который зависит от curl и параметра командной строки --resolve.

https://curl.haxx.se/docs/manpage.html#--resolve

Из языков более высокого уровня обычно можно вызвать curl.

person Tuan-Tu Tran    schedule 31.08.2020