【问题标题】:Override IP in HTTP Request覆盖 HTTP 请求中的 IP
【发布时间】:2011-01-03 06:30:37
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# c++ wininet


    【解决方案1】:

    你所要做的就是:

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

    【讨论】:

    • +1 似乎 Host 属性显然是在 .NET 4 中添加的。
    • 如果你在 4.0 之前用反射来做,它不会起作用,因为它会在发送请求时重新覆盖主机头。
    【解决方案2】:

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

    如果是这样的话,你也许可以这样做..

    在 C# 中使用 WebProxy:

    请参阅 Kayode Leonard's answer 了解 .NET 4 及更高版本。

    如果我的服务器在 67.223.227.171:8888 上运行,我将使用以下代码,但我需要在 Host: 标头中包含 www.example.com

    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 上运行,但我需要在Host: 标头中有www.example.com

    #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++ 示例代码。

    【讨论】:

    • @Alexandre - 刚刚尝试过 - 它看起来是一种非常新颖的方法(注意在文章​​中他更正了他对“CustomWebProxy”的使用并说它应该只是“WebProxy”)。但是,它似乎不起作用 - 请求似乎仍然具有原始主机标头。我可能错了——你不能轻易地使用 Fiddler 来调试它,因为 Fiddler 通过设置代理(这个解决方案专门覆盖)来工作。但是,使用 tcp 数据包嗅探器后,它看起来并不工作。真的很丢脸。
    • 我已经编辑了我的帖子。这有什么帮助吗?我似乎在这里得到了正确的标题。
    • +1 - 我有第二次尝试 - 我认为你是对的 - 这似乎确实有效。另外 - 通过将代理设置为 Fiddler 代理使其成为“Fiddler 可调试”的好地方。很明显,但我只是错过了 :) 这个技巧非常巧妙。
    • WINHTTP 有类似的东西吗?
    • @httpresearcher 看起来像。我添加了另一个示例。
    【解决方案3】:

    [注意,对 Kayode Leonard 的回答更进一步:在 .Net 4.0 中的请求中添加了 Host 属性,因此该回答已过时]

    认为您是说您希望能够覆盖给定主机的 IP 地址,而无需更改主机标头。

    例如,news.bbc.co.uk 映射到 IP 地址 212.58.226.139,但您希望能够将其映射到另一个 IP 地址,同时仍然呈现相同的 news.bbc .co.uk “Host” http 标头到被覆盖的地址。这就是您所说的通过覆盖 HOSTS 文件来实现的目标,这与 Jason 的回答略有不同,因为他不会显示原始的“Host”http 标头。

    我不相信您可以轻松做到这一点(尽管我将通过实验来找出答案!)。当然,您不能执行以下操作:

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

    因为这将失败并显示您无法修改“主机”标头的错误。

    如果您愿意降低 HttpWebRequest 的级别并以更高的 TCP 级别进行处理,您可能可以这样做,但我不确定如果不降低到该级别,您将如何处理它。

    [编辑]:在尝试过各种覆盖 HttpWebRequest 和 WebHeaderCollection 的方法后,我很确定不能以这种方式完成。但是,Alexandre Jasmin 的回答似乎是解决方案。

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-20
        • 2011-06-14
        • 2018-05-28
        • 2018-06-24
        相关资源
        最近更新 更多