覆盖HTTP请求中的IP

时间:2010-01-09 14:39:38

标签: c# c++ wininet

寻找发布HTTPwebrequest的方法,或使用浏览器控件或winhttp向URL发出请求,但覆盖从DNS查找到特定链接的IP地址。

尝试执行与HOSTS文件类似的操作,但无需修改此文件即可以编程方式执行。它可以是C#或C +

为什么我需要它,我发送请求的主机有多个IP,他们的域服务器正在对不同的IP进行负载平衡。试图强制请求到特定的IP,但我需要http请求中的主机仍然是原始主机。我需要以编程方式进行此操作,因为每次需要运行此测试时更改主机文件都非常耗时。

4 个答案:

答案 0 :(得分:13)

你所要做的就是:

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

答案 1 :(得分:6)

如果我理解正确,您必须使用虚拟主机向Web服务器发出http请求,但DNS尚未设置,因此您必须在URL中指定IP地址,但在主机中发送其他内容: 标题。

如果是这种情况,你可以这样做..

在C#中使用WebProxy:

请参阅Kayode Leonard's answer了解.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");

请参阅this link

在C ++中使用WinHttp:

使用WinHttp,您只需使用WinHttpAddRequestHeaders设置Host:标头。

再次,如果我的服务器在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 ++示例代码。

答案 2 :(得分:2)

[注意,请继续使用Kayode Leonard的答案:在.Net 4.0中将主机属性添加到请求中,使得此答案已过时]

你说你希望能够覆盖给定主机的ip地址,而不需要更改主机头。

例如,news.bbc.co.uk映射到IP地址212.58.226.139,但您希望能够将此映射到另一个IP地址,而仍然呈现相同的news.bbc .co.uk“主机”http标头到覆盖地址。这就是你所说的覆盖HOSTS文件所取得的成果,这与Jason的答案略有不同,因为他不会出现原始的“主机”http标题。

我不相信你能轻易做到这一点(虽然我即将试验找出来!)。当然你不能做到以下几点:

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

因为这会失败并显示错误,说您无法修改“主机”标题。

如果您愿意降低HttpWebRequest以下的级别并以更高的TCP级别进行交易,您可能会这样做,但我不确定如何在不降低该级别的情况下接近它。

[编辑]:玩过各种覆盖HttpWebRequest和WebHeaderCollection的方法,我很确定不能这样做。然而,Alexandre Jasmin的答案似乎就是解决方案。

答案 3 :(得分:0)

我要添加一个依赖于curl--resolve命令行选项的答案。

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

从高级语言开始,通常可以调用curl