我正在使用Jakarta Commons HttpClient 3.1编写一个负载测试工具,该工具需要针对不同的服务器,并假装它针对HTTP服务器中的正确虚拟主机。为此,我需要能够将请求中的“主机”HTTP标头设置为不同的主机名,然后是我要连接的实际主机名。
似乎很明显我应该使用Method.setRequestHeader("Host","fakehostname")
,但HttpClient只是忽略了这一点,并且总是在“Host”标题中发送我正在连接的真实主机名(我已经为“httpclient”启用了调试日志记录.wire“我可以做到这一点。”
如何覆盖标题以便HttpClient注意?
答案 0 :(得分:14)
在搜索了一些,并从Oleg的答案中得到了一个提示之后,我找到了方法HttpMethodParams::setVirtualHost()。
当HttpClient格式化请求时,它总是在发送请求之前自己创建“主机”标头 - 因此它不能被覆盖为标准标头。但是,在从URL生成“Host”标头的主机名之前,HttpClient会检查HttpMethodParams对象以查看用户是否要覆盖主机名。这只会覆盖主机名而不是端口,所以它更容易使用,虽然不像我想的那样直观。
使用它的代码可能如下所示:
Method m = new GetMethod("http://some-site/some/path");
m.getParams().setVirtualHost("some-other-site");
client.executeMethod(m);
因为我喜欢一个衬垫,所以也可以写成:
client.executeMethod(new GetMethod("http://some-site/some/path") {{
getParams().setVirtualHost("some-other-site"); }});
答案 1 :(得分:4)
以下适用于android:
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
InputStream stream_content=null;
try
{URL url=new URL("http://74.125.28.103/");
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Host", "www.google.com");
stream_content=conn.getInputStream();
}
catch (Exception e) {}
表示https网址:
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
InputStream stream_content=null;
try
{URL url=new URL("https://74.125.28.103/");
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
conn.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER );
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Host", "www.google.com");
stream_content=conn.getInputStream();
}
catch (Exception e) {}
答案 2 :(得分:3)
我相信您需要http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpHost.html:这可让您为特定连接配置主机。如果我理解正确,您可以使用execute
方法(请参阅http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/AbstractHttpClient.html#execute(org.apache.http.HttpHost,%20org.apache.http.HttpRequest))并将其传递给自定义HttpHost
对象,或者执行此操作:
让我知道它是如何运作的。
编辑:原则保持不变。
1.构造一个HttpHost实例,并将其传递给Host头(请参阅http://hc.apache.org/httpclient-legacy/apidocs/index.html?org/apache/commons/httpclient/HttpHost.html)。
2.创建一个HttpConfiguration实例,然后将你创建的HttpHost传递给它(参见http://hc.apache.org/httpclient-legacy/apidocs/index.html?org/apache/commons/httpclient/HostConfiguration.html)。
3.在具有该配置的HttpClient上使用execute
方法(请参阅http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpClient.html#executeMethod(org.apache.commons.httpclient.HostConfiguration,%20org.apache.commons.httpclient.HttpMethod))
答案 3 :(得分:2)
可以使用'http.virtual-host'
参数强制将任意(虚拟)主机名和端口强制为Host
请求标头的值,而不是从实际请求URI派生的值。但这仅适用于4.x API。