Как я могу переопределить заголовок «Host» в запросе при использовании Apache Commons HttpClient - PullRequest
9 голосов
/ 18 мая 2011

Я использую Jakarta Commons HttpClient 3.1 для написания инструмента нагрузочного тестирования, который должен быть нацелен на разные серверы и делать вид, будто он нацелен на правильный виртуальный хост в HTTP-сервере. Для этого мне нужно иметь возможность установить HTTP-заголовок «Host» в запросе на другое имя хоста, отличное от фактического имени хоста, к которому я подключаюсь.

Казалось довольно очевидным, что я должен использовать Method.setRequestHeader("Host","fakehostname"), но HttpClient просто игнорирует это и всегда отправляет реальное имя хоста, к которому я подключаюсь, в заголовке «Host» (я включил ведение журнала отладки для «httpclient.wire»). "и я могу это сделать специально).

Как мне переопределить заголовок, чтобы HttpClient обратил внимание?

Ответы [ 4 ]

14 голосов
/ 20 мая 2011

После дополнительного поиска и подсказки ответа Олега я нашел метод HttpMethodParams :: setVirtualHost () .

когда HttpClient форматирует запрос, он всегда создает сам заголовок «Host» непосредственно перед отправкой запроса, поэтому его нельзя переопределить как стандартный заголовок. Но перед тем, как имя хоста для заголовка «Host» будет сгенерировано из URL, 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"); }});
4 голосов
/ 21 августа 2013

Следующие работы на 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 URL:

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) {}
3 голосов
/ 18 мая 2011

Я полагаю, что вы хотите 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, передав ему заголовок своего хоста.
  2. Используйте его для создания экземпляра HttpRoute (см. http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/routing/HttpRoute.html)
  3. Передайте его менеджеру соединений, когда вы запрашиваете соединение (см. http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/ClientConnectionManager.html#requestConnection(org.apache.http.conn.routing.HttpRoute,%20java.lang.Object)).
  4. Используйте соединение с вашим методом: см. http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html для более подробной информации.

Дайте мне знать, как это работает.

РЕДАКТИРОВАТЬ: принцип остается прежним.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. Используйте метод executeна HttpClient с этой конфигурацией (см. http://hc.apache.org/httpclient-legacy/apidocs/org/apache/commons/httpclient/HttpClient.html#executeMethod(org.apache.commons.httpclient.HostConfiguration,%20org.apache.commons.httpclient.HttpMethod))

2 голосов
/ 18 мая 2011

Можно использовать параметр 'http.virtual-host', чтобы принудительно указать произвольное (виртуальное) имя хоста и порт в качестве значения заголовка запроса Host вместо тех, которые получены из фактического URI запроса. Это работает только с API 4.x.

...