1
0
Эх сурвалжийг харах

Tests: Remove HttpClient to only use one Http client

The HTTP client implementation used by the Elasticsearch REST tests is
backed by apache http client instead of a self written helper class,
that uses HttpUrlConnection. This commit removes the old simple HttpClient
class and uses the more powerful and reliable one for all tests.

It also fixes a minor bug, that when sending a 301 redirect, a Location
header needs to be added as well, which was uncovered by the switching
to the new client.

Closes #7003
Alexander Reelsen 11 жил өмнө
parent
commit
35e562343f

+ 4 - 1
src/main/java/org/elasticsearch/http/HttpServer.java

@@ -154,7 +154,10 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> {
             pluginName = path;
             sitePath = null;
             // If a trailing / is missing, we redirect to the right page #2654
-            channel.sendResponse(new BytesRestResponse(RestStatus.MOVED_PERMANENTLY, "text/html", "<head><meta http-equiv=\"refresh\" content=\"0; URL=" + request.rawPath() + "/\"></head>"));
+            String redirectUrl = request.rawPath() + "/";
+            BytesRestResponse restResponse = new BytesRestResponse(RestStatus.MOVED_PERMANENTLY, "text/html", "<head><meta http-equiv=\"refresh\" content=\"0; URL=" + redirectUrl + "></head>");
+            restResponse.addHeader("Location", redirectUrl);
+            channel.sendResponse(restResponse);
             return;
         } else {
             pluginName = path.substring(0, i1);

+ 10 - 8
src/test/java/org/elasticsearch/options/jsonp/JsonpOptionDisabledTest.java

@@ -19,15 +19,16 @@
 
 package org.elasticsearch.options.jsonp;
 
+import org.apache.http.impl.client.HttpClients;
 import org.elasticsearch.common.settings.ImmutableSettings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.http.HttpServerTransport;
 import org.elasticsearch.rest.RestController;
-import org.elasticsearch.rest.helper.HttpClient;
-import org.elasticsearch.rest.helper.HttpClientResponse;
 import org.elasticsearch.test.ElasticsearchIntegrationTest;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
+import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
+import org.elasticsearch.test.rest.client.http.HttpResponse;
 import org.junit.Test;
 
 import static org.hamcrest.Matchers.containsString;
@@ -55,11 +56,12 @@ public class JsonpOptionDisabledTest extends ElasticsearchIntegrationTest {
     @Test
     public void testThatJSONPisDisabled() throws Exception {
         // Make the HTTP request
-        HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
-        HttpClient httpClient = new HttpClient(httpServerTransport.boundAddress().publishAddress());
-        HttpClientResponse response = httpClient.request("/?callback=DisabledJSONPCallback");
-        assertThat(response.getHeader("Content-Type"), is("application/javascript"));
-        assertThat(response.response(), containsString("DisabledJSONPCallback("));
-        assertThat(response.response(), containsString("JSONP is disabled"));
+        HttpResponse response = new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class))
+                .path("/")
+                .addParam("callback", "DisabledJSONPCallback").execute();
+
+        assertThat(response.getHeaders().get("Content-Type"), is("application/javascript"));
+        assertThat(response.getBody(), containsString("DisabledJSONPCallback("));
+        assertThat(response.getBody(), containsString("JSONP is disabled"));
     }
 }

+ 7 - 8
src/test/java/org/elasticsearch/options/jsonp/JsonpOptionEnabledTest.java

@@ -19,15 +19,16 @@
 
 package org.elasticsearch.options.jsonp;
 
+import org.apache.http.impl.client.HttpClients;
 import org.elasticsearch.common.settings.ImmutableSettings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.http.HttpServerTransport;
 import org.elasticsearch.rest.RestController;
-import org.elasticsearch.rest.helper.HttpClient;
-import org.elasticsearch.rest.helper.HttpClientResponse;
 import org.elasticsearch.test.ElasticsearchIntegrationTest;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
+import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
+import org.elasticsearch.test.rest.client.http.HttpResponse;
 import org.junit.Test;
 
 import static org.hamcrest.Matchers.containsString;
@@ -50,11 +51,9 @@ public class JsonpOptionEnabledTest extends ElasticsearchIntegrationTest {
     @Test
     public void testThatJSONPisEnabled() throws Exception {
         // Make the HTTP request
-        HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
-        HttpClient httpClient = new HttpClient(httpServerTransport.boundAddress().publishAddress());
-        HttpClientResponse response = httpClient.request("/?callback=EnabledJSONPCallback");
-        assertThat(response.getHeader("Content-Type"), is("application/javascript"));
-        assertThat(response.response(), containsString("EnabledJSONPCallback("));
-        assertThat(response.response(), containsString("You Know, for Search"));
+        HttpResponse response = new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class)).path("/").addParam("callback", "EnabledJSONPCallback").execute();
+        assertThat(response.getHeaders().get("Content-Type"), is("application/javascript"));
+        assertThat(response.getBody(), containsString("EnabledJSONPCallback("));
+        assertThat(response.getBody(), containsString("You Know, for Search"));
     }
 }

+ 32 - 23
src/test/java/org/elasticsearch/plugin/PluginManagerTests.java

@@ -19,6 +19,8 @@
 package org.elasticsearch.plugin;
 
 import com.google.common.base.Predicate;
+import org.apache.http.impl.client.HttpClients;
+import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.ElasticsearchIllegalArgumentException;
 import org.elasticsearch.ElasticsearchTimeoutException;
 import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
@@ -33,11 +35,11 @@ import org.elasticsearch.http.HttpServerTransport;
 import org.elasticsearch.node.internal.InternalSettingsPreparer;
 import org.elasticsearch.plugins.PluginManager;
 import org.elasticsearch.rest.RestStatus;
-import org.elasticsearch.rest.helper.HttpClient;
-import org.elasticsearch.rest.helper.HttpClientResponse;
 import org.elasticsearch.test.ElasticsearchIntegrationTest;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
 import org.elasticsearch.test.junit.annotations.Network;
+import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
+import org.elasticsearch.test.rest.client.http.HttpResponse;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -205,31 +207,37 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
         assertThat(pluginFound, is(true));
     }
 
-    private void assertPluginAvailable(String pluginName) throws InterruptedException {
-        HttpServerTransport httpServerTransport = internalCluster().getInstance(HttpServerTransport.class);
-        final HttpClient httpClient = new HttpClient(httpServerTransport.boundAddress().publishAddress());
-        logger.info("--> tested http address [{}]", httpServerTransport.info().getAddress());
+    private void assertPluginAvailable(String pluginName) throws InterruptedException, IOException {
+        final HttpRequestBuilder httpRequestBuilder = getHttpRequestBuilder();
 
         //checking that the http connector is working properly
         // We will try it for some seconds as it could happen that the REST interface is not yet fully started
         assertThat(awaitBusy(new Predicate<Object>() {
             public boolean apply(Object obj) {
-                HttpClientResponse response = httpClient.request("");
-                if (response.errorCode() != RestStatus.OK.getStatus()) {
-                    // We want to trace what's going on here before failing the test
-                    logger.info("--> error caught [{}], headers [{}]", response.errorCode(), response.getHeaders());
-                    logger.info("--> cluster state [{}]", internalCluster().clusterService().state());
-                    return false;
+                try {
+                    HttpResponse response = httpRequestBuilder.method("GET").path("/").execute();
+                    if (response.getStatusCode() != RestStatus.OK.getStatus()) {
+                        // We want to trace what's going on here before failing the test
+                        logger.info("--> error caught [{}], headers [{}]", response.getStatusCode(), response.getHeaders());
+                        logger.info("--> cluster state [{}]", internalCluster().clusterService().state());
+                        return false;
+                    }
+                    return true;
+                } catch (IOException e) {
+                    throw new ElasticsearchException("HTTP problem", e);
                 }
-                return true;
             }
         }, 5, TimeUnit.SECONDS), equalTo(true));
 
 
         //checking now that the plugin is available
-        HttpClientResponse response = httpClient.request("_plugin/" + pluginName + "/");
+        HttpResponse response = getHttpRequestBuilder().method("GET").path("/_plugin/" + pluginName + "/").execute();
         assertThat(response, notNullValue());
-        assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
+        assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+    }
+
+    private HttpRequestBuilder getHttpRequestBuilder() {
+        return new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class));
     }
 
     @Test
@@ -300,7 +308,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
     @Test
     @Network
     public void testInstallPluginWithElasticsearchDownloadService() throws IOException {
-        assumeTrue(isDownloadServiceWorking("http://download.elasticsearch.org/", "elasticsearch/ci-test.txt"));
+        assumeTrue(isDownloadServiceWorking("download.elasticsearch.org", 80, "/elasticsearch/ci-test.txt"));
         singlePluginInstallAndRemove("elasticsearch/elasticsearch-transport-thrift/1.5.0", null);
     }
 
@@ -313,7 +321,7 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
     @Test
     @Network
     public void testInstallPluginWithMavenCentral() throws IOException {
-        assumeTrue(isDownloadServiceWorking("http://search.maven.org/", "/"));
+        assumeTrue(isDownloadServiceWorking("search.maven.org", 80, "/"));
         singlePluginInstallAndRemove("org.elasticsearch/elasticsearch-transport-thrift/1.5.0", null);
     }
 
@@ -326,20 +334,21 @@ public class PluginManagerTests extends ElasticsearchIntegrationTest {
     @Test
     @Network
     public void testInstallPluginWithGithub() throws IOException {
-        assumeTrue(isDownloadServiceWorking("https://github.com/", "/"));
+        assumeTrue(isDownloadServiceWorking("github.com", 443, "/"));
         singlePluginInstallAndRemove("elasticsearch/kibana", null);
     }
 
-    private boolean isDownloadServiceWorking(String url, String resource) {
-        HttpClient client = new HttpClient(url);
+    private boolean isDownloadServiceWorking(String host, int port, String resource) {
         try {
-            if (client.request(resource).errorCode() != 200) {
-                logger.warn("[{}{}] download service is not working. Disabling current test.", url, resource);
+            String protocol = port == 443 ? "https" : "http";
+            HttpResponse response = new HttpRequestBuilder(HttpClients.createDefault()).protocol(protocol).host(host).port(port).path(resource).execute();
+            if (response.getStatusCode() != 200) {
+                logger.warn("[{}{}] download service is not working. Disabling current test.", host, resource);
                 return false;
             }
             return true;
         } catch (Throwable t) {
-            logger.warn("[{}{}] download service is not working. Disabling current test.", url, resource);
+            logger.warn("[{}{}] download service is not working. Disabling current test.", host, resource);
         }
         return false;
     }

+ 12 - 17
src/test/java/org/elasticsearch/plugin/ResponseHeaderPluginTests.java

@@ -18,21 +18,19 @@
  */
 package org.elasticsearch.plugin;
 
-import com.google.common.collect.Maps;
+import org.apache.http.impl.client.HttpClients;
 import org.elasticsearch.common.settings.ImmutableSettings;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.http.HttpServerTransport;
 import org.elasticsearch.plugin.responseheader.TestResponseHeaderPlugin;
 import org.elasticsearch.rest.RestStatus;
-import org.elasticsearch.rest.helper.HttpClient;
-import org.elasticsearch.rest.helper.HttpClientResponse;
 import org.elasticsearch.test.ElasticsearchIntegrationTest;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
+import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
+import org.elasticsearch.test.rest.client.http.HttpResponse;
 import org.junit.Test;
 
-import java.util.Map;
-
-import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
+import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
 import static org.hamcrest.Matchers.equalTo;
 
 /**
@@ -53,19 +51,16 @@ public class ResponseHeaderPluginTests extends ElasticsearchIntegrationTest {
     @Test
     public void testThatSettingHeadersWorks() throws Exception {
         ensureGreen();
-        HttpClientResponse response = httpClient().request("/_protected");
-        assertThat(response.errorCode(), equalTo(RestStatus.UNAUTHORIZED.getStatus()));
-        assertThat(response.getHeader("Secret"), equalTo("required"));
+        HttpResponse response = httpClient().method("GET").path("/_protected").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.UNAUTHORIZED.getStatus()));
+        assertThat(response.getHeaders().get("Secret"), equalTo("required"));
 
-        Map<String, String> headers = Maps.newHashMap();
-        headers.put("Secret", "password");
-        HttpClientResponse authResponse = httpClient().request("GET", "_protected", headers);
-        assertThat(authResponse.errorCode(), equalTo(RestStatus.OK.getStatus()));
-        assertThat(authResponse.getHeader("Secret"), equalTo("granted"));
+        HttpResponse authResponse = httpClient().method("GET").path("/_protected").addHeader("Secret", "password").execute();
+        assertThat(authResponse.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+        assertThat(authResponse.getHeaders().get("Secret"), equalTo("granted"));
     }
 
-    private HttpClient httpClient() {
-        HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
-        return new HttpClient(httpServerTransport.boundAddress().publishAddress());
+    private HttpRequestBuilder httpClient() {
+        return new HttpRequestBuilder(HttpClients.createDefault()).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class));
     }
 }

+ 27 - 23
src/test/java/org/elasticsearch/plugin/SitePluginTests.java

@@ -18,20 +18,23 @@
  */
 package org.elasticsearch.plugin;
 
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.http.HttpServerTransport;
 import org.elasticsearch.rest.RestStatus;
-import org.elasticsearch.rest.helper.HttpClient;
-import org.elasticsearch.rest.helper.HttpClientResponse;
 import org.elasticsearch.test.ElasticsearchIntegrationTest;
 import org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
+import org.elasticsearch.test.rest.client.http.HttpRequestBuilder;
+import org.elasticsearch.test.rest.client.http.HttpResponse;
 import org.junit.Test;
 
 import java.io.File;
 import java.net.URISyntaxException;
 
 import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
-import static org.elasticsearch.test.ElasticsearchIntegrationTest.*;
+import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
 
@@ -56,22 +59,23 @@ public class SitePluginTests extends ElasticsearchIntegrationTest {
         }
     }
 
-    public HttpClient httpClient() {
-        HttpServerTransport httpServerTransport = internalCluster().getDataNodeInstance(HttpServerTransport.class);
-        return new HttpClient(httpServerTransport.boundAddress().publishAddress());
+    public HttpRequestBuilder httpClient() {
+        RequestConfig.Builder builder = RequestConfig.custom().setRedirectsEnabled(false);
+        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(builder.build()).build();
+        return new HttpRequestBuilder(httpClient).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class));
     }
 
     @Test
     public void testRedirectSitePlugin() throws Exception {
         // We use an HTTP Client to test redirection
-        HttpClientResponse response = httpClient().request("/_plugin/dummy");
-        assertThat(response.errorCode(), equalTo(RestStatus.MOVED_PERMANENTLY.getStatus()));
-        assertThat(response.response(), containsString("/_plugin/dummy/"));
+        HttpResponse response = httpClient().method("GET").path("/_plugin/dummy").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.MOVED_PERMANENTLY.getStatus()));
+        assertThat(response.getBody(), containsString("/_plugin/dummy/"));
 
         // We test the real URL
-        response = httpClient().request("/_plugin/dummy/");
-        assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
-        assertThat(response.response(), containsString("<title>Dummy Site Plugin</title>"));
+        response = httpClient().method("GET").path("/_plugin/dummy/").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+        assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>"));
     }
 
     /**
@@ -79,9 +83,9 @@ public class SitePluginTests extends ElasticsearchIntegrationTest {
      */
     @Test
     public void testAnyPage() throws Exception {
-        HttpClientResponse response = httpClient().request("/_plugin/dummy/index.html");
-        assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
-        assertThat(response.response(), containsString("<title>Dummy Site Plugin</title>"));
+        HttpResponse response = httpClient().path("/_plugin/dummy/index.html").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+        assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>"));
     }
 
     /**
@@ -90,15 +94,15 @@ public class SitePluginTests extends ElasticsearchIntegrationTest {
      */
     @Test
     public void testWelcomePageInSubDirs() throws Exception {
-        HttpClientResponse response = httpClient().request("/_plugin/subdir/dir/");
-        assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
-        assertThat(response.response(), containsString("<title>Dummy Site Plugin (subdir)</title>"));
+        HttpResponse response = httpClient().path("/_plugin/subdir/dir/").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+        assertThat(response.getBody(), containsString("<title>Dummy Site Plugin (subdir)</title>"));
 
-        response = httpClient().request("/_plugin/subdir/dir_without_index/");
-        assertThat(response.errorCode(), equalTo(RestStatus.FORBIDDEN.getStatus()));
+        response = httpClient().path("/_plugin/subdir/dir_without_index/").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.FORBIDDEN.getStatus()));
 
-        response = httpClient().request("/_plugin/subdir/dir_without_index/page.html");
-        assertThat(response.errorCode(), equalTo(RestStatus.OK.getStatus()));
-        assertThat(response.response(), containsString("<title>Dummy Site Plugin (page)</title>"));
+        response = httpClient().path("/_plugin/subdir/dir_without_index/page.html").execute();
+        assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+        assertThat(response.getBody(), containsString("<title>Dummy Site Plugin (page)</title>"));
     }
 }

+ 0 - 120
src/test/java/org/elasticsearch/rest/helper/HttpClient.java

@@ -1,120 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.elasticsearch.rest.helper;
-
-import com.google.common.base.Charsets;
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.common.io.Streams;
-import org.elasticsearch.common.transport.InetSocketTransportAddress;
-import org.elasticsearch.common.transport.TransportAddress;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.InetSocketAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-
-public class HttpClient {
-
-    private final URL baseUrl;
-
-    public HttpClient(TransportAddress transportAddress) {
-        InetSocketAddress address = ((InetSocketTransportAddress) transportAddress).address();
-        try {
-            baseUrl = new URL("http", address.getAddress().getHostAddress(), address.getPort(), "/");
-        } catch (MalformedURLException e) {
-            throw new ElasticsearchException("", e);
-        }
-    }
-
-    public HttpClient(String url) {
-        try {
-            baseUrl = new URL(url);
-        } catch (MalformedURLException e) {
-            throw new ElasticsearchException("", e);
-        }
-    }
-
-    public HttpClient(URL url) {
-        baseUrl = url;
-    }
-
-    public HttpClientResponse request(String path) {
-        return request("GET", path);
-    }
-
-    public HttpClientResponse request(String method, String path) {
-        return request(method, path, null);
-    }
-
-    public HttpClientResponse request(String method, String path, Map<String, String> headers) {
-        URL url;
-        try {
-            url = new URL(baseUrl, path);
-        } catch (MalformedURLException e) {
-            throw new ElasticsearchException("Cannot parse " + path, e);
-        }
-
-        HttpURLConnection urlConnection;
-        try {
-            urlConnection = (HttpURLConnection) url.openConnection();
-            urlConnection.setRequestMethod(method);
-            if (headers != null) {
-                for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
-                    urlConnection.setRequestProperty(headerEntry.getKey(), headerEntry.getValue());
-                }
-            }
-            urlConnection.connect();
-        } catch (IOException e) {
-            throw new ElasticsearchException("", e);
-        }
-
-        int errorCode = -1;
-        Map<String, List<String>> respHeaders = null;
-        try {
-            errorCode = urlConnection.getResponseCode();
-            respHeaders = urlConnection.getHeaderFields();
-            InputStream inputStream = urlConnection.getInputStream();
-            String body = null;
-            try {
-                body = Streams.copyToString(new InputStreamReader(inputStream, Charsets.UTF_8));
-            } catch (IOException e1) {
-                throw new ElasticsearchException("problem reading error stream", e1);
-            }
-            return new HttpClientResponse(body, errorCode, respHeaders, null);
-        } catch (IOException e) {
-            InputStream errStream = urlConnection.getErrorStream();
-            String body = null;
-            if (errStream != null) {
-                try {
-                    body = Streams.copyToString(new InputStreamReader(errStream, Charsets.UTF_8));
-                } catch (IOException e1) {
-                    throw new ElasticsearchException("problem reading error stream", e1);
-                }
-            }
-            return new HttpClientResponse(body, errorCode, respHeaders, e);
-        } finally {
-            urlConnection.disconnect();
-        }
-    }
-}

+ 0 - 63
src/test/java/org/elasticsearch/rest/helper/HttpClientResponse.java

@@ -1,63 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.elasticsearch.rest.helper;
-
-import java.util.List;
-import java.util.Map;
-
-public class HttpClientResponse {
-    private final String response;
-    private final int errorCode;
-    private Map<String, List<String>> headers;
-    private final Throwable e;
-
-    public HttpClientResponse(String response, int errorCode, Map<String, List<String>> headers,  Throwable e) {
-        this.response = response;
-        this.errorCode = errorCode;
-        this.headers = headers;
-        this.e = e;
-    }
-
-    public String response() {
-        return response;
-    }
-
-    public int errorCode() {
-        return errorCode;
-    }
-
-    public Throwable cause() {
-        return e;
-    }
-
-    public Map<String, List<String>> getHeaders() {
-        return headers;
-    }
-
-    public String getHeader(String name) {
-        if (headers == null) {
-            return null;
-        }
-        List<String> vals = headers.get(name);
-        if (vals == null || vals.size() == 0) {
-            return null;
-        }
-        return vals.iterator().next();
-    }
-}

+ 35 - 17
src/test/java/org/elasticsearch/test/rest/client/http/HttpRequestBuilder.java

@@ -20,6 +20,7 @@ package org.elasticsearch.test.rest.client.http;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.Maps;
+import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.*;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -27,6 +28,9 @@ import org.apache.lucene.util.IOUtils;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
+import org.elasticsearch.common.transport.InetSocketTransportAddress;
+import org.elasticsearch.common.transport.TransportAddress;
+import org.elasticsearch.http.HttpServerTransport;
 
 import java.io.IOException;
 import java.net.URI;
@@ -46,6 +50,8 @@ public class HttpRequestBuilder {
 
     private final CloseableHttpClient httpClient;
 
+    private String protocol = "http";
+
     private String host;
 
     private int port;
@@ -54,6 +60,8 @@ public class HttpRequestBuilder {
 
     private final Map<String, String> params = Maps.newHashMap();
 
+    private final Map<String, String> headers = Maps.newHashMap();
+
     private String method = HttpGetWithEntity.METHOD_NAME;
 
     private String body;
@@ -67,6 +75,11 @@ public class HttpRequestBuilder {
         return this;
     }
 
+    public HttpRequestBuilder httpTransport(HttpServerTransport httpServerTransport) {
+        InetSocketTransportAddress transportAddress = (InetSocketTransportAddress) httpServerTransport.boundAddress().publishAddress();
+        return host(transportAddress.address().getHostName()).port(transportAddress.address().getPort());
+    }
+
     public HttpRequestBuilder port(int port) {
         this.port = port;
         return this;
@@ -82,6 +95,16 @@ public class HttpRequestBuilder {
         return this;
     }
 
+    public HttpRequestBuilder addHeader(String name, String value) {
+        this.headers.put(name, value);
+        return this;
+    }
+
+    public HttpRequestBuilder protocol(String protocol) {
+        this.protocol = protocol;
+        return this;
+    }
+
     public HttpRequestBuilder method(String method) {
         this.method = method;
         return this;
@@ -95,26 +118,21 @@ public class HttpRequestBuilder {
     }
 
     public HttpResponse execute() throws IOException {
-        CloseableHttpResponse closeableHttpResponse = null;
-        try {
-            HttpUriRequest httpUriRequest = buildRequest();
-            if (logger.isTraceEnabled()) {
-                StringBuilder stringBuilder = new StringBuilder(httpUriRequest.getMethod()).append(" ").append(httpUriRequest.getURI());
-                if (Strings.hasLength(body)) {
-                    stringBuilder.append("\n").append(body);
-                }
-                logger.trace("sending request \n{}", stringBuilder.toString());
+        HttpUriRequest httpUriRequest = buildRequest();
+        if (logger.isTraceEnabled()) {
+            StringBuilder stringBuilder = new StringBuilder(httpUriRequest.getMethod()).append(" ").append(httpUriRequest.getURI());
+            if (Strings.hasLength(body)) {
+                stringBuilder.append("\n").append(body);
             }
-            closeableHttpResponse = httpClient.execute(httpUriRequest);
+            logger.trace("sending request \n{}", stringBuilder.toString());
+        }
+        for (Map.Entry<String, String> entry : this.headers.entrySet()) {
+            httpUriRequest.addHeader(entry.getKey(), entry.getValue());
+        }
+        try (CloseableHttpResponse closeableHttpResponse = httpClient.execute(httpUriRequest)) {
             HttpResponse httpResponse = new HttpResponse(httpUriRequest, closeableHttpResponse);
             logger.trace("got response \n{}\n{}", closeableHttpResponse, httpResponse.hasBody() ? httpResponse.getBody() : "");
             return httpResponse;
-        } finally {
-            try {
-                IOUtils.close(closeableHttpResponse);
-            } catch (IOException e) {
-                logger.error("error closing http response", e);
-            }
         }
     }
 
@@ -152,7 +170,7 @@ public class HttpRequestBuilder {
             query = Joiner.on('&').withKeyValueSeparator("=").join(params);
         }
         try {
-            return new URI("http", null, host, port, path, query, null);
+            return new URI(protocol, null, host, port, path, query, null);
         } catch (URISyntaxException e) {
             throw new IllegalArgumentException(e);
         }

+ 11 - 0
src/test/java/org/elasticsearch/test/rest/client/http/HttpResponse.java

@@ -18,6 +18,7 @@
  */
 package org.elasticsearch.test.rest.client.http;
 
+import org.apache.http.Header;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpHead;
 import org.apache.http.client.methods.HttpUriRequest;
@@ -26,6 +27,8 @@ import org.elasticsearch.common.logging.ESLogger;
 import org.elasticsearch.common.logging.Loggers;
 
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Response obtained from an http request
@@ -39,11 +42,15 @@ public class HttpResponse {
     private final int statusCode;
     private final String reasonPhrase;
     private final String body;
+    private final Map<String, String> headers = new HashMap<>();
 
     HttpResponse(HttpUriRequest httpRequest, CloseableHttpResponse httpResponse) {
         this.httpRequest = httpRequest;
         this.statusCode = httpResponse.getStatusLine().getStatusCode();
         this.reasonPhrase = httpResponse.getStatusLine().getReasonPhrase();
+        for (Header header : httpResponse.getAllHeaders()) {
+            this.headers.put(header.getName(), header.getValue());
+        }
         if (httpResponse.getEntity() != null) {
             try {
                 this.body = EntityUtils.toString(httpResponse.getEntity(), HttpRequestBuilder.DEFAULT_CHARSET);
@@ -86,6 +93,10 @@ public class HttpResponse {
         return !HttpHead.METHOD_NAME.equals(httpRequest.getMethod());
     }
 
+    public Map<String, String> getHeaders() {
+        return headers;
+    }
+
     @Override
     public String toString() {
         StringBuilder stringBuilder = new StringBuilder(statusCode).append(" ").append(reasonPhrase);