Repository: wiremock/wiremock (language: java)

Issue:
Upgrade to HTTP client 5.x
Track the latest and greatest now that it's GA.

Also, fix #627


Discussion / hints:
Started with a first attempt here: https://github.com/wiremock/wiremock/compare/master...timtebeek:http-client-5.x
Not sure if I'll be able to get every last detail working, but it's a start. :)

Figured to first get this working as much as possible, and only once that's done separately and gradually improve handling of closeables for instance.
I've been doing a bit of thinking about this recently and I think there's an opportunity to make WireMock more portable while doing this.

A long term goal I have is to split WireMock up a bit, creating a smaller core with abstractions around key integration points such as the proxy HTTP client.

One advantage of this is that users on other platforms e.g. Android and (possibly) some serverless frameworks can choose an implementation that works well for them in terms of compatibility/performance/size etc.

Another is that, since Java 11+ now has a decent HTTP client and server, the core version could work without the need for 3rd party dependencies for either.

So since we already have a `Request` and `Response` pair of interfaces, I'd like to propose also adding our own `HttpClient` interface around these, which is settable in `WireMockConfiguration` and defaults to the HTTPClient 5.x implementation.

What do you think?

Fix patch:
diff --git a/build.gradle b/build.gradle
index 2e356c61ec..54328c22d5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -49,7 +49,6 @@ dependencies {
     compile "com.fasterxml.jackson.core:jackson-core:$versions.jackson",
         "com.fasterxml.jackson.core:jackson-annotations:$versions.jackson",
         "com.fasterxml.jackson.core:jackson-databind:$versions.jackson"
-    compile "org.apache.httpcomponents:httpclient:4.5.13"
     compile "org.apache.httpcomponents.client5:httpclient5:5.1"
     compile "org.xmlunit:xmlunit-core:$versions.xmlUnit"
     compile "org.xmlunit:xmlunit-legacy:$versions.xmlUnit", {
@@ -105,7 +104,6 @@ dependencies {
 
     testCompile "org.eclipse.jetty:jetty-client:$versions.jetty"
     testCompile "org.eclipse.jetty.http2:http2-http-client-transport:$versions.jetty"
-    testCompile 'org.apache.httpcomponents:httpmime:4.5.13'
 
     testRuntime "org.slf4j:slf4j-api:1.7.32"
     testRuntime "org.apache.logging.log4j:log4j-slf4j-impl:2.14.1"
diff --git a/docs-v2/_docs/https.md b/docs-v2/_docs/https.md
index 63d022e96a..b750020ddd 100644
--- a/docs-v2/_docs/https.md
+++ b/docs-v2/_docs/https.md
@@ -78,7 +78,7 @@ specify a trust store containing the certificate(s).
 `javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?`: Usually means you've tried to connect to the
 HTTP port with a client that's expecting HTTPS (i.e. has https:// in the URL).
 
-`org.apache.http.NoHttpResponseException: The target server failed to respond`: Could mean you've tried to connect to the HTTPS port with a
+`org.apache.hc.core5.http.NoHttpResponseException: The target server failed to respond`: Could mean you've tried to connect to the HTTPS port with a
 client expecting HTTP.
 
 `javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target`: You are using WireMock's default (self-signed) TLS certificate or another certificate that isn't signed by a CA. In this case you need to specifically configure your HTTP client to trust the certificate being presented, or to trust all certificates. Here is an example of [how to do this with the Apache HTTP client](https://github.com/tomakehurst/wiremock/blob/{{ site.wiremock_version }}/src/main/java/com/github/tomakehurst/wiremock/http/HttpClientFactory.java).
diff --git a/src/main/java/com/github/tomakehurst/wiremock/http/GenericHttpUriRequest.java b/src/main/java/com/github/tomakehurst/wiremock/http/GenericHttpUriRequest.java
deleted file mode 100644
index 707cc7ce42..0000000000
--- a/src/main/java/com/github/tomakehurst/wiremock/http/GenericHttpUriRequest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2011 Thomas Akehurst
- *
- * Licensed 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 com.github.tomakehurst.wiremock.http;
-
-import org.apache.http.client.methods.HttpRequestBase;
-
-import java.net.URI;
-
-public class GenericHttpUriRequest extends HttpRequestBase {
-
-    private final String methodName;
-
-    public GenericHttpUriRequest(String methodName, String url) {
-        this.methodName = methodName;
-        setURI(URI.create(url));
-    }
-
-    @Override
-    public String getMethod() {
-        return methodName;
-    }
-}
diff --git a/wiremock-webhooks-extension/build.gradle b/wiremock-webhooks-extension/build.gradle
index 566fc104ba..45660d3a1d 100644
--- a/wiremock-webhooks-extension/build.gradle
+++ b/wiremock-webhooks-extension/build.gradle
@@ -25,7 +25,7 @@ group 'org.wiremock'
 
 dependencies {
     compileOnly project(":")
-    implementation "org.apache.httpcomponents:httpclient:4.5.13"
+    compile "org.apache.httpcomponents.client5:httpclient5:5.1"
 
     testImplementation project(":")
     testImplementation(platform('org.junit:junit-bom:5.8.1'))
diff --git a/wiremock-webhooks-extension/src/main/java/org/wiremock/webhooks/Webhooks.java b/wiremock-webhooks-extension/src/main/java/org/wiremock/webhooks/Webhooks.java
index 94f7517fe4..e441b9e767 100644
--- a/wiremock-webhooks-extension/src/main/java/org/wiremock/webhooks/Webhooks.java
+++ b/wiremock-webhooks-extension/src/main/java/org/wiremock/webhooks/Webhooks.java
@@ -9,23 +9,25 @@
 import com.github.tomakehurst.wiremock.extension.responsetemplating.TemplateEngine;
 import com.github.tomakehurst.wiremock.http.HttpHeader;
 import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.config.SocketConfig;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.impl.NoConnectionReuseStrategy;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.io.SocketConfig;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
+import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
 
 import java.util.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
 import static com.github.tomakehurst.wiremock.common.LocalNotifier.notifier;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.stream.Collectors.toList;
 
 public class Webhooks extends PostServeAction {
@@ -66,12 +68,16 @@ private static CloseableHttpClient createHttpClient() {
                 .disableCookieManagement()
                 .disableRedirectHandling()
                 .disableContentCompression()
-                .setMaxConnTotal(1000)
-                .setMaxConnPerRoute(1000)
-                .setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build())
-                .setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(30000).build())
-                .setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE)
-                .setKeepAliveStrategy((response, context) -> 0)
+                .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
+                        .setDefaultSocketConfig(SocketConfig.custom()
+                                .setSoTimeout(Timeout.ofMilliseconds(30000))
+                                .build())
+                        .setMaxConnPerRoute(1000)
+                        .setMaxConnTotal(1000)
+                        .setValidateAfterInactivity(TimeValue.ofSeconds(5))  // TODO Verify duration
+                        .build())
+                .setConnectionReuseStrategy((request, response, context) -> false)
+                .setKeepAliveStrategy((response, context) -> TimeValue.ZERO_MILLISECONDS)
                 .build();
     }
 
@@ -85,7 +91,7 @@ public void doAction(final ServeEvent serveEvent, final Admin admin, final Param
         final Notifier notifier = notifier();
 
         WebhookDefinition definition;
-        HttpUriRequest request;
+        ClassicHttpRequest request;
         try {
             definition = WebhookDefinition.from(parameters);
             for (WebhookTransformer transformer : transformers) {
@@ -106,7 +112,7 @@ public void doAction(final ServeEvent serveEvent, final Admin admin, final Param
                                 String.format("Webhook %s request to %s returned status %s\n\n%s",
                                         finalDefinition.getMethod(),
                                         finalDefinition.getUrl(),
-                                        response.getStatusLine(),
+                                        response.getCode(),
                                         EntityUtils.toString(response.getEntity())
                                 )
                         );
@@ -149,8 +155,8 @@ private String renderTemplate(Object context, String value) {
         return templateEngine.getUncachedTemplate(value).apply(context);
     }
 
-    private static HttpUriRequest buildRequest(WebhookDefinition definition) {
-        final RequestBuilder requestBuilder = RequestBuilder.create(definition.getMethod())
+    private static ClassicHttpRequest buildRequest(WebhookDefinition definition) {
+        final ClassicRequestBuilder requestBuilder = ClassicRequestBuilder.create(definition.getMethod())
                 .setUri(definition.getUrl());
 
         for (HttpHeader header : definition.getHeaders().all()) {
@@ -160,7 +166,7 @@ private static HttpUriRequest buildRequest(WebhookDefinition definition) {
         }
 
         if (definition.getRequestMethod().hasEntity() && definition.hasBody()) {
-            requestBuilder.setEntity(new ByteArrayEntity(definition.getBinaryBody()));
+            requestBuilder.setEntity(new ByteArrayEntity(definition.getBinaryBody(), ContentType.DEFAULT_BINARY));
         }
 
         return requestBuilder.build();


Test patch:
diff --git a/src/test/java/com/github/tomakehurst/wiremock/AdminApiTest.java b/src/test/java/com/github/tomakehurst/wiremock/AdminApiTest.java
index b0a1acb022..f6583dded7 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/AdminApiTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/AdminApiTest.java
@@ -31,7 +31,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.toomuchcoding.jsonassert.JsonAssertion;
 import com.toomuchcoding.jsonassert.JsonVerifiable;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.Matchers;
@@ -55,8 +55,7 @@
 import static com.github.tomakehurst.wiremock.testsupport.WireMatchers.equalsMultiLine;
 import static com.github.tomakehurst.wiremock.testsupport.WireMatchers.matches;
 import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
-import static net.javacrumbs.jsonunit.JsonMatchers.jsonStringPartEquals;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
 import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/BindAddressTest.java b/src/test/java/com/github/tomakehurst/wiremock/BindAddressTest.java
index a1ebf6af1d..a3b97cffcd 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/BindAddressTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/BindAddressTest.java
@@ -15,13 +15,13 @@
  */
 package com.github.tomakehurst.wiremock;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -48,7 +48,7 @@ public class BindAddressTest {
     private String nonBindAddress;
     private WireMockServer wireMockServer;
 
-    final HttpClient client = HttpClient4Factory.createClient();
+    final CloseableHttpClient client = HttpClientFactory.createClient();
 
     @BeforeEach
     public void prepare() throws Exception {
@@ -98,12 +98,12 @@ public void shouldRespondInTheBindAddressOnlyOnHttps() throws Exception {
     }
 
     private int getStatusViaHttps(String host) throws Exception {
-        HttpResponse localhostResponse = client.execute(RequestBuilder
+        ClassicHttpResponse localhostResponse = client.execute(ClassicRequestBuilder
             .get("https://" + host + ":" + wireMockServer.httpsPort() + "/bind-test")
             .build()
         );
 
-        int status = localhostResponse.getStatusLine().getStatusCode();
+        int status = localhostResponse.getCode();
         EntityUtils.consume(localhostResponse.getEntity());
         return status;
     }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/GzipAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/GzipAcceptanceTest.java
index 2c7d904ae2..d4bc9576a9 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/GzipAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/GzipAcceptanceTest.java
@@ -20,10 +20,10 @@
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.client.entity.GzipCompressingEntity;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.client5.http.entity.GzipCompressingEntity;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.eclipse.jetty.util.Jetty;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/Http2AcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/Http2AcceptanceTest.java
index efbe5fea4c..50b9612b79 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/Http2AcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/Http2AcceptanceTest.java
@@ -15,11 +15,11 @@
  */
 package com.github.tomakehurst.wiremock;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.junit.jupiter.api.Test;
@@ -62,13 +62,13 @@ public void supportsHttp2PlaintextConnections() throws Exception {
 
     @Test
     public void supportsHttp1_1Connections() throws Exception {
-        CloseableHttpClient client = HttpClient4Factory.createClient();
+        CloseableHttpClient client = HttpClientFactory.createClient();
 
         wm.stubFor(get("/thing").willReturn(ok("HTTP/1.1 response")));
 
         HttpGet get = new HttpGet("https://localhost:" + wm.getRuntimeInfo().getHttpsPort() + "/thing");
         try (CloseableHttpResponse response = client.execute(get)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
     }
 }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/HttpsAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/HttpsAcceptanceTest.java
index f9386146bb..cd87d42f76 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/HttpsAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/HttpsAcceptanceTest.java
@@ -20,21 +20,19 @@
 import com.github.tomakehurst.wiremock.core.Options;
 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
 import com.github.tomakehurst.wiremock.http.Fault;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.google.common.io.Resources;
-import org.apache.http.HttpResponse;
-import org.apache.http.MalformedChunkCodingException;
-import org.apache.http.NoHttpResponseException;
-import org.apache.http.ProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.ssl.SSLContexts;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
+import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy;
+import org.apache.hc.core5.http.*;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.ssl.SSLContexts;
 import org.hamcrest.Matchers;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
@@ -72,7 +70,7 @@ public class HttpsAcceptanceTest {
 
     private WireMockServer wireMockServer;
     private WireMockServer proxy;
-    private HttpClient httpClient;
+    private CloseableHttpClient httpClient;
 
     @AfterEach
     public void serverShutdown() {
@@ -101,7 +99,7 @@ public void shouldReturnOnlyOnHttpsWhenHttpDisabled() throws Exception {
             wireMockServer = new WireMockServer(config);
             wireMockServer.start();
             WireMock.configureFor("https", "localhost", wireMockServer.httpsPort());
-            httpClient = HttpClient4Factory.createClient();
+            httpClient = HttpClientFactory.createClient();
 
             stubFor(get(urlEqualTo("/https-test")).willReturn(aResponse().withStatus(200).withBody("HTTPS content")));
 
@@ -159,7 +157,7 @@ public void randomDataOnSocketFault() {
                 aResponse()
                         .withFault(Fault.RANDOM_DATA_THEN_CLOSE)));
 
-        getAndAssertUnderlyingExceptionInstanceClass(url("/random/data"), ProtocolException.class);
+        getAndAssertUnderlyingExceptionInstanceClass(url("/random/data"), NoHttpResponseException.class);
     }
 
     @Test
@@ -250,7 +248,7 @@ public void supportsProxyingWhenTargetRequiresClientCert() throws Exception {
 
         HttpGet get = new HttpGet("http://localhost:" + proxy.port() + "/client-cert-proxy");
         HttpResponse response = httpClient.execute(get);
-        assertThat(response.getStatusLine().getStatusCode(), is(200));
+        assertThat(response.getCode(), is(200));
     }
 
     @Test
@@ -264,7 +262,7 @@ public void proxyingFailsWhenTargetServiceRequiresClientCertificatesAndProxyDoes
 
         HttpGet get = new HttpGet("http://localhost:" + proxy.port() + "/client-cert-proxy-fail");
         HttpResponse response = httpClient.execute(get);
-        assertThat(response.getStatusLine().getStatusCode(), is(500));
+        assertThat(response.getCode(), is(500));
     }
 
     private String url(String path) {
@@ -292,7 +290,7 @@ private void getAndAssertUnderlyingExceptionInstanceClass(String url, Class<?> e
 
     private String contentFor(String url) throws Exception {
         HttpGet get = new HttpGet(url);
-        HttpResponse response = httpClient.execute(get);
+        ClassicHttpResponse response = httpClient.execute(get);
         String content = EntityUtils.toString(response.getEntity());
         return content;
     }
@@ -313,7 +311,7 @@ private void startServerEnforcingClientCert(String keystorePath, String truststo
         wireMockServer.start();
         WireMock.configureFor("https", "localhost", wireMockServer.httpsPort());
 
-        httpClient = HttpClient4Factory.createClient();
+        httpClient = HttpClientFactory.createClient();
     }
 
     private void startServerWithKeystore(String keystorePath, String keystorePassword, String keyManagerPassword) {
@@ -328,7 +326,7 @@ private void startServerWithKeystore(String keystorePath, String keystorePasswor
         wireMockServer.start();
         WireMock.configureFor(wireMockServer.port());
 
-        httpClient = HttpClient4Factory.createClient();
+        httpClient = HttpClientFactory.createClient();
     }
 
     private void startServerWithKeystore(String keystorePath) {
@@ -349,18 +347,21 @@ static String secureContentFor(String url, String clientTrustStore, String trust
                 .setProtocol("TLS")
                 .build();
 
-        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
+        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
                 sslcontext,
                 null, // supported protocols
                 null,  // supported cipher suites
                 NoopHostnameVerifier.INSTANCE);
 
+        PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
+                .setSSLSocketFactory(sslSocketFactory).build();
+
         CloseableHttpClient httpClient = HttpClients.custom()
-                .setSSLSocketFactory(sslsf)
+                .setConnectionManager(connectionManager)
                 .build();
 
         HttpGet get = new HttpGet(url);
-        HttpResponse response = httpClient.execute(get);
+        ClassicHttpResponse response = httpClient.execute(get);
         String content = EntityUtils.toString(response.getEntity());
         return content;
     }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyAcceptanceTest.java
index 0f5929a399..13e017c611 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyAcceptanceTest.java
@@ -24,14 +24,16 @@
 import com.github.tomakehurst.wiremock.testsupport.TestFiles;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import org.apache.http.HttpHost;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.DnsResolver;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.SystemDefaultDnsResolver;
+import org.apache.hc.client5.http.DnsResolver;
+import org.apache.hc.client5.http.SystemDefaultDnsResolver;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
+import org.apache.hc.core5.http.HttpHost;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.HttpProxy;
 import org.eclipse.jetty.client.Origin;
@@ -248,9 +250,12 @@ public void certificatesSignedWithUsersRootCertificate() throws Exception {
             KeyStore trustStore = HttpsAcceptanceTest.readKeyStore(PROXY_KEYSTORE_WITH_CUSTOM_CA_CERT, "password");
 
             // given
-            CloseableHttpClient httpClient = HttpClients.custom()
+            PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                     .setDnsResolver(new CustomLocalTldDnsResolver("internal"))
                     .setSSLSocketFactory(sslSocketFactoryThatTrusts(trustStore))
+                    .build();
+            CloseableHttpClient httpClient = HttpClients.custom()
+                    .setConnectionManager(connectionManager)
                     .setProxy(new HttpHost("localhost", proxyWithCustomCaKeyStore.port()))
                     .build();
 
@@ -278,9 +283,12 @@ public void certificatesSignedWithGeneratedRootCertificate() throws Exception {
         KeyStore trustStore = HttpsAcceptanceTest.readKeyStore(NO_PREEXISTING_KEYSTORE_PATH, "password");
 
         // given
-        CloseableHttpClient httpClient = HttpClients.custom()
+        PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                 .setDnsResolver(new CustomLocalTldDnsResolver("internal"))
                 .setSSLSocketFactory(sslSocketFactoryThatTrusts(trustStore))
+                .build();
+        CloseableHttpClient httpClient = HttpClients.custom()
+                .setConnectionManager(connectionManager)
                 .setProxy(new HttpHost("localhost", proxy.getRuntimeInfo().getHttpPort()))
                 .build();
 
@@ -371,13 +379,21 @@ public CustomLocalTldDnsResolver(String tldToSendToLocalhost) {
 
         @Override
         public InetAddress[] resolve(String host) throws UnknownHostException {
-
             if (host.endsWith("." + tldToSendToLocalhost)) {
                 return new InetAddress[] { InetAddress.getLocalHost() };
             } else {
                 return new SystemDefaultDnsResolver().resolve(host);
             }
         }
+
+        @Override
+        public String resolveCanonicalHostname(String host) throws UnknownHostException {
+            final InetAddress[] resolvedAddresses = resolve(host);
+            if (resolvedAddresses.length > 0) {
+                return resolvedAddresses[0].getCanonicalHostName();
+            }
+            return host;
+        }
     }
 
     private static String tempNonExistingPath(String prefix, String filename) {
diff --git a/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyClientAuthAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyClientAuthAcceptanceTest.java
index cd29809e52..ec10682aa5 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyClientAuthAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/HttpsBrowserProxyClientAuthAcceptanceTest.java
@@ -16,15 +16,17 @@
 package com.github.tomakehurst.wiremock;
 
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
-import org.apache.http.HttpHost;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.ssl.SSLContexts;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
+import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.ssl.SSLContexts;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
@@ -77,7 +79,7 @@ public void canDoClientAuthEndToEndWhenProxying() throws Exception {
         CloseableHttpClient testClient = buildHttpClient();
         CloseableHttpResponse response = testClient.execute(new HttpGet(target.url("/whatever")));
 
-        assertThat(response.getStatusLine().getStatusCode(), is(HTTP_OK));
+        assertThat(response.getCode(), is(HTTP_OK));
         assertThat(EntityUtils.toString(response.getEntity()), is("Success"));
     }
 
@@ -104,8 +106,12 @@ private CloseableHttpClient buildHttpClient() throws Exception {
                 .disableAutomaticRetries()
                 .disableCookieManagement()
                 .disableRedirectHandling()
-                .setSSLContext(sslcontext)
-                .setSSLHostnameVerifier(new NoopHostnameVerifier())
+                .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
+                        .setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
+                                .setSslContext(sslcontext)
+                                .setHostnameVerifier(new NoopHostnameVerifier())
+                                .build())
+                        .build())
                 .setProxy(proxyInfo)
                 .build();
     }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/JvmProxyConfigAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/JvmProxyConfigAcceptanceTest.java
index 9456ab01a2..e33e597ee9 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/JvmProxyConfigAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/JvmProxyConfigAcceptanceTest.java
@@ -1,12 +1,12 @@
 package com.github.tomakehurst.wiremock;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.http.JvmProxyConfigurer;
 import com.google.common.io.ByteStreams;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
@@ -14,11 +14,12 @@
 import java.net.HttpURLConnection;
 import java.net.URL;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.nullValue;
 
 public class JvmProxyConfigAcceptanceTest {
 
@@ -47,7 +48,7 @@ public void configuresHttpProxyingOnlyFromAWireMockServer() throws Exception {
 
     @Test
     public void configuresHttpsProxyingOnlyFromAWireMockServer() throws Exception {
-        CloseableHttpClient httpClient = HttpClient4Factory.createClient();
+        CloseableHttpClient httpClient = HttpClientFactory.createClient();
 
         wireMockServer = new WireMockServer(wireMockConfig().dynamicPort().enableBrowserProxying(true));
         wireMockServer.start();
diff --git a/src/test/java/com/github/tomakehurst/wiremock/MultipartBodyMatchingAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/MultipartBodyMatchingAcceptanceTest.java
index 2a86056274..c73bc7453f 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/MultipartBodyMatchingAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/MultipartBodyMatchingAcceptanceTest.java
@@ -15,29 +15,29 @@
  */
 package com.github.tomakehurst.wiremock;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
 import org.junit.jupiter.api.Test;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static com.github.tomakehurst.wiremock.testsupport.MultipartBody.part;
 import static java.util.Collections.singletonList;
-import static org.apache.http.entity.ContentType.MULTIPART_FORM_DATA;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
-import static org.hamcrest.Matchers.is;
+import static org.apache.hc.core5.http.ContentType.MULTIPART_FORM_DATA;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
 
 public class MultipartBodyMatchingAcceptanceTest extends AcceptanceTestBase {
 
-    HttpClient httpClient = HttpClient4Factory.createClient();
+    CloseableHttpClient httpClient = HttpClientFactory.createClient();
 
     @Test
     public void acceptsAMultipartRequestContainingATextAndAFilePart() throws Exception {
@@ -51,7 +51,7 @@ public void acceptsAMultipartRequestContainingATextAndAFilePart() throws Excepti
             .willReturn(ok())
         );
 
-        HttpUriRequest request = RequestBuilder
+        ClassicHttpRequest request = ClassicRequestBuilder
             .post(wireMockServer.baseUrl() + "/multipart")
             .setEntity(MultipartEntityBuilder.create()
                 .addTextBody("text", "hello")
@@ -60,11 +60,11 @@ public void acceptsAMultipartRequestContainingATextAndAFilePart() throws Excepti
             )
             .build();
 
-        HttpResponse response = httpClient.execute(request);
+        ClassicHttpResponse response = httpClient.execute(request);
 
         assertThat(
                 EntityUtils.toString(response.getEntity()),
-                response.getStatusLine().getStatusCode(), is(200));
+                response.getCode(), is(200));
     }
 
     @Test
@@ -76,7 +76,7 @@ public void handlesAbsenceOfPartsInAMultipartRequest() throws Exception {
             .willReturn(ok())
         );
 
-        HttpUriRequest request = RequestBuilder
+        ClassicHttpRequest request = ClassicRequestBuilder
             .post(wireMockServer.baseUrl() + "/empty-multipart")
             .setHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
             .setEntity(new StringEntity("", MULTIPART_FORM_DATA))
@@ -84,7 +84,7 @@ public void handlesAbsenceOfPartsInAMultipartRequest() throws Exception {
 
         HttpResponse response = httpClient.execute(request);
 
-        assertThat(response.getStatusLine().getStatusCode(), is(404));
+        assertThat(response.getCode(), is(404));
     }
 
     /**
@@ -102,7 +102,7 @@ public void acceptsAMultipartMixedRequestContainingATextAndAFilePart() throws Ex
                 .willReturn(ok())
         );
 
-        HttpUriRequest request = RequestBuilder
+        ClassicHttpRequest request = ClassicRequestBuilder
                 .post(wireMockServer.baseUrl() + "/multipart-mixed")
                 .setEntity(MultipartEntityBuilder.create()
                         .setMimeSubtype("mixed")
@@ -112,11 +112,11 @@ public void acceptsAMultipartMixedRequestContainingATextAndAFilePart() throws Ex
                 )
                 .build();
 
-        HttpResponse response = httpClient.execute(request);
+        ClassicHttpResponse response = httpClient.execute(request);
 
         assertThat(
                 EntityUtils.toString(response.getEntity()),
-                response.getStatusLine().getStatusCode(), is(200));
+                response.getCode(), is(200));
     }
 
     /**
@@ -134,7 +134,7 @@ public void acceptsAMultipartRelatedRequestContainingATextAndAFilePart() throws
                 .willReturn(ok())
         );
 
-        HttpUriRequest request = RequestBuilder
+        ClassicHttpRequest request = ClassicRequestBuilder
                 .post(wireMockServer.baseUrl() + "/multipart-related")
                 .setEntity(MultipartEntityBuilder.create()
                         .setMimeSubtype("related")
@@ -144,11 +144,11 @@ public void acceptsAMultipartRelatedRequestContainingATextAndAFilePart() throws
                 )
                 .build();
 
-        HttpResponse response = httpClient.execute(request);
+        ClassicHttpResponse response = httpClient.execute(request);
 
         assertThat(
                 EntityUtils.toString(response.getEntity()),
-                response.getStatusLine().getStatusCode(), is(200));
+                response.getCode(), is(200));
     }
 
     // https://github.com/tomakehurst/wiremock/issues/1179
diff --git a/src/test/java/com/github/tomakehurst/wiremock/NearMissesRuleAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/NearMissesRuleAcceptanceTest.java
index c22e991529..66df39c5f1 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/NearMissesRuleAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/NearMissesRuleAcceptanceTest.java
@@ -25,7 +25,7 @@
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import ignored.ManyUnmatchedRequestsTest;
 import ignored.SingleUnmatchedRequestTest;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/NotMatchedPageAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/NotMatchedPageAcceptanceTest.java
index 5b7efd6890..6f3ed6a310 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/NotMatchedPageAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/NotMatchedPageAcceptanceTest.java
@@ -27,18 +27,14 @@
 import com.github.tomakehurst.wiremock.extension.requestfilter.StubRequestFilter;
 import com.github.tomakehurst.wiremock.http.Request;
 import com.github.tomakehurst.wiremock.http.ResponseDefinition;
-import com.github.tomakehurst.wiremock.testsupport.TestHttpHeader;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import com.github.tomakehurst.wiremock.verification.diff.PlainTextDiffRenderer;
 import com.github.tomakehurst.wiremock.verification.notmatched.NotMatchedRenderer;
-import com.github.tomakehurst.wiremock.verification.notmatched.PlainTextStubNotMatchedRenderer;
-import org.apache.http.HttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
-import java.util.Collections;
 import java.util.List;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
@@ -49,9 +45,9 @@
 import static com.github.tomakehurst.wiremock.verification.notmatched.PlainTextStubNotMatchedRenderer.CONSOLE_WIDTH_HEADER_KEY;
 import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
 import static java.util.Collections.singletonList;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
 
 public class NotMatchedPageAcceptanceTest {
 
@@ -258,7 +254,7 @@ public void showsNotFoundDiffMessageWhenRequestBodyIsGZipped() {
                 .willReturn(ok())
         );
 
-        ByteArrayEntity entity = new ByteArrayEntity(Gzip.gzip("{\"id\":\"wrong\"}"));
+        ByteArrayEntity entity = new ByteArrayEntity(Gzip.gzip("{\"id\":\"wrong\"}"), ContentType.DEFAULT_BINARY);
         WireMockResponse response = testClient.post("/gzip", entity, withHeader("Content-Encoding", "gzip"));
 
         assertThat(response.statusCode(), is(404));
diff --git a/src/test/java/com/github/tomakehurst/wiremock/ProxyAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/ProxyAcceptanceTest.java
index 61cfc33464..b272bb27c6 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/ProxyAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/ProxyAcceptanceTest.java
@@ -15,18 +15,11 @@
  */
 package com.github.tomakehurst.wiremock;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.util.Arrays;
-import java.util.Collection;
-
 import com.github.tomakehurst.wiremock.client.WireMock;
 import com.github.tomakehurst.wiremock.common.ProxySettings;
 import com.github.tomakehurst.wiremock.core.Options;
 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import com.github.tomakehurst.wiremock.verification.LoggedRequest;
@@ -34,31 +27,37 @@
 import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.client.entity.GzipCompressingEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.hc.client5.http.classic.methods.HttpHead;
+import org.apache.hc.client5.http.entity.GzipCompressingEntity;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.hamcrest.Matchers;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.Collection;
+
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static com.github.tomakehurst.wiremock.testsupport.TestHttpHeader.withHeader;
 import static com.google.common.collect.Iterables.getLast;
 import static com.google.common.net.HttpHeaders.CONTENT_ENCODING;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.hamcrest.MatcherAssert.assertThat;
 
 public class ProxyAcceptanceTest {
 
@@ -224,7 +223,7 @@ public void handle(HttpExchange exchange) throws IOException {
 		
         proxy.register(post(urlEqualTo("/binary")).willReturn(aResponse().proxiedFrom("http://localhost:" + server.getAddress().getPort()).withBody(bytes)));
         
-        WireMockResponse post = testClient.post("/binary", new ByteArrayEntity(bytes));
+        WireMockResponse post = testClient.post("/binary", new ByteArrayEntity(bytes, ContentType.DEFAULT_BINARY));
 		assertThat(post.statusCode(), is(200));
 		assertThat(post.binaryContent(), Matchers.equalTo(bytes));
 	}
@@ -249,10 +248,10 @@ public void returnsContentLengthHeaderFromTargetResponseIfPresentAndChunkedEncod
         target.register(head(urlPathEqualTo(path)).willReturn(ok().withHeader("Content-Length", "4")));
         proxy.register(any(anyUrl()).willReturn(aResponse().proxiedFrom(targetServiceBaseUrl)));
 
-        CloseableHttpClient httpClient = HttpClient4Factory.createClient();
+        CloseableHttpClient httpClient = HttpClientFactory.createClient();
         HttpHead request = new HttpHead(proxyingService.baseUrl() + path);
         try (CloseableHttpResponse response = httpClient.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
             assertThat(response.getFirstHeader("Content-Length").getValue(), is("4"));
         }
     }
@@ -265,10 +264,10 @@ public void returnsContentLengthHeaderFromTargetResponseIfPresentAndChunkedEncod
         target.register(head(urlPathEqualTo(path)).willReturn(ok().withHeader("Content-Length", "4")));
         proxy.register(any(anyUrl()).willReturn(aResponse().proxiedFrom(targetServiceBaseUrl)));
 
-        CloseableHttpClient httpClient = HttpClient4Factory.createClient();
+        CloseableHttpClient httpClient = HttpClientFactory.createClient();
         HttpHead request = new HttpHead(proxyingService.baseUrl() + path);
         try (CloseableHttpResponse response = httpClient.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
             assertThat(response.getFirstHeader("Content-Length").getValue(), is("4"));
         }
     }
@@ -460,7 +459,7 @@ public void contextPathsWithTrailingSlashesArePreserved() {
     }
 
     /**
-     * NOTE: {@link org.apache.http.client.HttpClient} always has a / when the context path is empty.
+     * NOTE: {@link org.apache.hc.core5.http.client.HttpClient} always has a / when the context path is empty.
      * This is also the behaviour of curl (see e.g. <a href="https://curl.haxx.se/mail/archive-2016-08/0027.html">here</a>)
      */
     @Test
diff --git a/src/test/java/com/github/tomakehurst/wiremock/RecordApiAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/RecordApiAcceptanceTest.java
index da058e86d4..8c20afb7dc 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/RecordApiAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/RecordApiAcceptanceTest.java
@@ -23,7 +23,7 @@
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import com.google.common.base.Predicate;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/RecordingDslAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/RecordingDslAcceptanceTest.java
index 31b1750d9b..a5598bc6f7 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/RecordingDslAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/RecordingDslAcceptanceTest.java
@@ -24,9 +24,9 @@
 import com.github.tomakehurst.wiremock.stubbing.StubMapping;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.client.entity.GzipCompressingEntity;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.client5.http.entity.GzipCompressingEntity;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.hamcrest.Matchers;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -42,12 +42,12 @@
 import static com.github.tomakehurst.wiremock.testsupport.TestHttpHeader.withHeader;
 import static com.github.tomakehurst.wiremock.testsupport.WireMatchers.findMappingWithUrl;
 import static com.google.common.net.HttpHeaders.CONTENT_TYPE;
-import static org.apache.http.entity.ContentType.APPLICATION_OCTET_STREAM;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_OCTET_STREAM;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.nullValue;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.hamcrest.MatcherAssert.assertThat;
 
 public class RecordingDslAcceptanceTest extends AcceptanceTestBase {
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/RequestQueryAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/RequestQueryAcceptanceTest.java
index 38f41fca45..7189b24bdf 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/RequestQueryAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/RequestQueryAcceptanceTest.java
@@ -23,9 +23,8 @@
 import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
 import com.github.tomakehurst.wiremock.testsupport.MappingJsonSamples;
 import com.github.tomakehurst.wiremock.verification.LoggedRequest;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.ContentType;
-import static com.google.common.base.Charsets.UTF_8;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
@@ -38,9 +37,10 @@
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static com.github.tomakehurst.wiremock.testsupport.WireMatchers.hasExactly;
 import static com.github.tomakehurst.wiremock.testsupport.WireMatchers.isToday;
+import static com.google.common.base.Charsets.UTF_8;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
 
 public class RequestQueryAcceptanceTest extends AcceptanceTestBase {
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAcceptanceTest.java
index 832537635d..4724c5d722 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAcceptanceTest.java
@@ -17,14 +17,14 @@
 
 import com.github.tomakehurst.wiremock.core.Options;
 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import com.github.tomakehurst.wiremock.matching.UrlPattern;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.HttpResponse;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -37,10 +37,10 @@
 
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static java.lang.Thread.sleep;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class ResponseDelayAcceptanceTest {
@@ -56,12 +56,12 @@ public class ResponseDelayAcceptanceTest {
         .options(WireMockConfiguration.options().port(Options.DYNAMIC_PORT).httpsPort(Options.DYNAMIC_PORT))
         .build();
 
-    private HttpClient httpClient;
+    private CloseableHttpClient httpClient;
     private WireMockTestClient testClient;
 
     @BeforeEach
     public void init() {
-        httpClient = HttpClient4Factory.createClient(SOCKET_TIMEOUT_MILLISECONDS);
+        httpClient = HttpClientFactory.createClient(SOCKET_TIMEOUT_MILLISECONDS);
         testClient = new WireMockTestClient(wireMockRule.getRuntimeInfo().getHttpPort());
     }
 
@@ -176,7 +176,7 @@ public void requestIsSuccessfulWhenDelayIsShorterThanSocketTimeout() throws Exce
                         .withFixedDelay(SHORTER_THAN_SOCKET_TIMEOUT)));
 
         final HttpResponse execute = httpClient.execute(new HttpGet(wireMockRule.url("/delayed")));
-        assertThat(execute.getStatusLine().getStatusCode(), is(200));
+        assertThat(execute.getCode(), is(200));
     }
 
     @Test
@@ -225,7 +225,7 @@ public void run() {
                 try {
                     HttpGet request = new HttpGet(wireMockRule.url("/delayed"));
                     final HttpResponse execute = httpClient.execute(request);
-                    assertThat(execute.getStatusLine().getStatusCode(), is(200));
+                    assertThat(execute.getCode(), is(200));
                     success.set(true);
                 } catch (Throwable e) {
                     e.printStackTrace();
diff --git a/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAsynchronousAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAsynchronousAcceptanceTest.java
index 42f71de0fa..a0248c5d21 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAsynchronousAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/ResponseDelayAsynchronousAcceptanceTest.java
@@ -16,12 +16,12 @@
 package com.github.tomakehurst.wiremock;
 
 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import com.google.common.base.Stopwatch;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
@@ -69,7 +69,7 @@ public void addsFixedDelayAsynchronously() throws Exception {
 
         for (Future<TimedHttpResponse> response: responses) {
             TimedHttpResponse timedResponse = response.get();
-            assertThat(timedResponse.response.getStatusLine().getStatusCode(), is(200));
+            assertThat(timedResponse.response.getCode(), is(200));
             assertThat(timedResponse.milliseconds, greaterThan((double) SHORTER_THAN_SOCKET_TIMEOUT));
         }
     }
@@ -82,7 +82,7 @@ public void addsRandomDelayAsynchronously() throws Exception {
 
         for (Future<TimedHttpResponse> response: responses) {
             TimedHttpResponse timedResponse = response.get();
-            assertThat(timedResponse.response.getStatusLine().getStatusCode(), is(200));
+            assertThat(timedResponse.response.getCode(), is(200));
             assertThat(timedResponse.milliseconds, greaterThan(100.0));
         }
     }
@@ -94,7 +94,7 @@ private List<Callable<TimedHttpResponse>> getHttpRequestCallables(int requestCou
             requests.add(new Callable<TimedHttpResponse>() {
                 @Override
                 public TimedHttpResponse call() throws Exception {
-                    CloseableHttpResponse response = HttpClient4Factory
+                    CloseableHttpResponse response = HttpClientFactory
                         .createClient(SOCKET_TIMEOUT_MILLISECONDS)
                         .execute(new HttpGet(wireMockRule.url("/delayed")));
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/ResponseDribbleAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/ResponseDribbleAcceptanceTest.java
index 8180a687ae..30d4663d52 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/ResponseDribbleAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/ResponseDribbleAcceptanceTest.java
@@ -15,13 +15,13 @@
  */
 package com.github.tomakehurst.wiremock;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import org.apache.commons.io.IOUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.hamcrest.Matcher;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -29,13 +29,17 @@
 
 import java.io.IOException;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static com.github.tomakehurst.wiremock.core.Options.DYNAMIC_PORT;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
 import static com.github.tomakehurst.wiremock.testsupport.Assumptions.doNotRunOnMacOSXInCI;
-import static org.hamcrest.Matchers.*;
-import static org.hamcrest.Matchers.lessThan;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.closeTo;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
 
 public class ResponseDribbleAcceptanceTest {
 
@@ -52,12 +56,12 @@ public class ResponseDribbleAcceptanceTest {
         .options(options().port(DYNAMIC_PORT).httpsPort(DYNAMIC_PORT))
         .build();
 
-    private HttpClient httpClient;
+    private CloseableHttpClient httpClient;
 
     @BeforeEach
     public void init() throws IOException {
         stubFor(get("/warmup").willReturn(ok()));
-        httpClient = HttpClient4Factory.createClient(SOCKET_TIMEOUT_MILLISECONDS);
+        httpClient = HttpClientFactory.createClient(SOCKET_TIMEOUT_MILLISECONDS);
         // Warm up the server
         httpClient.execute(new HttpGet(wireMockRule.url("/warmup")));
     }
@@ -72,11 +76,11 @@ public void requestIsSuccessfulButTakesLongerThanSocketTimeoutWhenDribbleIsEnabl
                     .withChunkedDribbleDelay(BODY_BYTES.length, DOUBLE_THE_SOCKET_TIMEOUT)));
 
         long start = System.currentTimeMillis();
-        HttpResponse response = httpClient.execute(new HttpGet(wireMockRule.url("/delayedDribble")));
+        ClassicHttpResponse response = httpClient.execute(new HttpGet(wireMockRule.url("/delayedDribble")));
         byte[] responseBody = IOUtils.toByteArray(response.getEntity().getContent());
         int duration = (int) (System.currentTimeMillis() - start);
 
-        assertThat(response.getStatusLine().getStatusCode(), is(200));
+        assertThat(response.getCode(), is(200));
         assertThat(responseBody, is(BODY_BYTES));
         assertThat(duration, greaterThanOrEqualTo(SOCKET_TIMEOUT_MILLISECONDS));
         assertThat((double) duration, isWithinTolerance(DOUBLE_THE_SOCKET_TIMEOUT, TOLERANCE));
@@ -94,11 +98,11 @@ public void servesAStringBodyInChunks() throws Exception {
                 .withChunkedDribbleDelay(2, TOTAL_TIME)));
 
         long start = System.currentTimeMillis();
-        HttpResponse response = httpClient.execute(new HttpGet(wireMockRule.url("/delayedDribble")));
+        ClassicHttpResponse response = httpClient.execute(new HttpGet(wireMockRule.url("/delayedDribble")));
         String responseBody = EntityUtils.toString(response.getEntity());
         double duration = (double) (System.currentTimeMillis() - start);
 
-        assertThat(response.getStatusLine().getStatusCode(), is(200));
+        assertThat(response.getCode(), is(200));
         assertThat(responseBody, is("Send this in many pieces please!!!"));
         assertThat(duration, isWithinTolerance(TOTAL_TIME, TOLERANCE));
     }
@@ -112,11 +116,11 @@ public void requestIsSuccessfulAndBelowSocketTimeoutWhenDribbleIsDisabled() thro
                     .withBody(BODY_BYTES)));
 
         long start = System.currentTimeMillis();
-        HttpResponse response = httpClient.execute(new HttpGet(wireMockRule.url("/nonDelayedDribble")));
+        ClassicHttpResponse response = httpClient.execute(new HttpGet(wireMockRule.url("/nonDelayedDribble")));
         byte[] responseBody = IOUtils.toByteArray(response.getEntity().getContent());
         int duration = (int) (System.currentTimeMillis() - start);
 
-        assertThat(response.getStatusLine().getStatusCode(), is(200));
+        assertThat(response.getCode(), is(200));
         assertThat(BODY_BYTES, is(responseBody));
         assertThat(duration, lessThan(SOCKET_TIMEOUT_MILLISECONDS));
     }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/StubbingAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/StubbingAcceptanceTest.java
index 871c0c1e17..5f5d971424 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/StubbingAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/StubbingAcceptanceTest.java
@@ -20,12 +20,11 @@
 import com.github.tomakehurst.wiremock.matching.StringValuePattern;
 import com.github.tomakehurst.wiremock.stubbing.StubMapping;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
-import org.apache.http.HttpHeaders;
-import org.apache.http.MalformedChunkCodingException;
-import org.apache.http.NoHttpResponseException;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.MalformedChunkCodingException;
+import org.apache.hc.core5.http.NoHttpResponseException;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
@@ -42,6 +41,8 @@
 import java.util.UUID;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.any;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
 import static com.github.tomakehurst.wiremock.common.DateTimeTruncation.FIRST_MINUTE_OF_HOUR;
 import static com.github.tomakehurst.wiremock.common.DateTimeUnit.HOURS;
 import static com.github.tomakehurst.wiremock.http.RequestMethod.GET;
@@ -51,16 +52,12 @@
 import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
 import static java.net.HttpURLConnection.HTTP_OK;
 import static java.util.Collections.singletonList;
-import static org.apache.http.entity.ContentType.APPLICATION_JSON;
-import static org.apache.http.entity.ContentType.APPLICATION_OCTET_STREAM;
-import static org.apache.http.entity.ContentType.APPLICATION_XML;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_JSON;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_OCTET_STREAM;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_XML;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.*;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -404,7 +401,7 @@ public void randomDataOnSocketFault() {
                 aResponse()
                 .withFault(Fault.RANDOM_DATA_THEN_CLOSE)));
 
-		getAndAssertUnderlyingExceptionInstanceClass("/random/data", ClientProtocolException.class);
+		getAndAssertUnderlyingExceptionInstanceClass("/random/data", NoHttpResponseException.class);
 	}
 
 	@Test
@@ -488,7 +485,7 @@ public void doesNotAttemptToMatchXmlBodyWhenStubMappingDoesNotHaveOne() {
             .withRequestBody(equalToXml("<some-xml />"))
             .willReturn(aResponse().withStatus(201)));
 
-        WireMockResponse response = testClient.request("OPTIONS", "/no-body");
+        WireMockResponse response = testClient.options("/no-body");
         assertThat(response.statusCode(), is(200));
     }
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/StubbingWithBrowserProxyAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/StubbingWithBrowserProxyAcceptanceTest.java
index 730b2f585f..1505e58799 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/StubbingWithBrowserProxyAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/StubbingWithBrowserProxyAcceptanceTest.java
@@ -17,15 +17,16 @@
 
 import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
-import org.apache.http.HttpHost;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.conn.DnsResolver;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.conn.SystemDefaultDnsResolver;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.DnsResolver;
+import org.apache.hc.client5.http.SystemDefaultDnsResolver;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -56,7 +57,9 @@ public class StubbingWithBrowserProxyAcceptanceTest {
     @BeforeAll
     public static void init() {
         client = HttpClientBuilder.create()
-                .setDnsResolver(new CustomLocalTldDnsResolver("internal"))
+                .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
+                        .setDnsResolver(new CustomLocalTldDnsResolver("internal"))
+                        .build())
                 .setProxy(new HttpHost("localhost", wm.getRuntimeInfo().getHttpPort()))
                 .build();
     }
@@ -68,7 +71,7 @@ public void matchesOnHostname() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://righthost.internal/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://righthost.internal/mypath").build();
         makeRequestAndAssertOk(request);
     }
 
@@ -79,7 +82,7 @@ public void doesNotMatchOnHostnameWhenIncorrect() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://wronghost.internal/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://wronghost.internal/mypath").build();
         makeRequestAndAssertNotOk(request);
     }
 
@@ -89,7 +92,7 @@ public void matchesAnyHostnameWhenNotSpecified() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://whatever.internal/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://whatever.internal/mypath").build();
         makeRequestAndAssertOk(request);
     }
     
@@ -100,7 +103,7 @@ public void matchesPortNumber() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://localhost:1234/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://localhost:1234/mypath").build();
         makeRequestAndAssertOk(request);
     }
 
@@ -111,7 +114,7 @@ public void doesNotMatchOnPortNumberWhenIncorrect() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://localhost:4321/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://localhost:4321/mypath").build();
         makeRequestAndAssertNotOk(request);
     }
 
@@ -122,7 +125,7 @@ public void matchesOnScheme() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://whatever/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://whatever/mypath").build();
         makeRequestAndAssertOk(request);
     }
 
@@ -133,17 +136,17 @@ public void doesNotMatchWhenSchemeIncorrect() throws Exception {
                 .willReturn(ok(EXPECTED_RESPONSE_BODY))
         );
 
-        HttpUriRequest request = RequestBuilder.get("http://whatever/mypath").build();
+        ClassicHttpRequest request = ClassicRequestBuilder.get("http://whatever/mypath").build();
         makeRequestAndAssertNotOk(request);
     }
     
-    private void makeRequestAndAssertOk(HttpUriRequest request) throws Exception {
+    private void makeRequestAndAssertOk(ClassicHttpRequest request) throws Exception {
         try (CloseableHttpResponse response = client.execute(request)) {
             assertThat(EntityUtils.toString(response.getEntity()), is(EXPECTED_RESPONSE_BODY));
         }
     }
 
-    private void makeRequestAndAssertNotOk(HttpUriRequest request) throws Exception {
+    private void makeRequestAndAssertNotOk(ClassicHttpRequest request) throws Exception {
         try (CloseableHttpResponse response = client.execute(request)) {
             assertThat(EntityUtils.toString(response.getEntity()), not(is(EXPECTED_RESPONSE_BODY)));
         }
@@ -159,12 +162,20 @@ public CustomLocalTldDnsResolver(String tldToSendToLocalhost) {
 
         @Override
         public InetAddress[] resolve(String host) throws UnknownHostException {
-
             if (host.endsWith("." + tldToSendToLocalhost)) {
                 return new InetAddress[] { InetAddress.getLocalHost() };
             } else {
                 return new SystemDefaultDnsResolver().resolve(host);
             }
         }
+
+        @Override
+        public String resolveCanonicalHostname(String host) throws UnknownHostException {
+            final InetAddress[] resolvedAddresses = resolve(host);
+            if (resolvedAddresses.length > 0) {
+                return resolvedAddresses[0].getCanonicalHostName();
+            }
+            return host;
+        }
     }
 }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/TransferEncodingAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/TransferEncodingAcceptanceTest.java
index d58b9f84ab..e38434edbd 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/TransferEncodingAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/TransferEncodingAcceptanceTest.java
@@ -16,21 +16,24 @@
 package com.github.tomakehurst.wiremock;
 
 import com.github.tomakehurst.wiremock.core.Options;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static com.github.tomakehurst.wiremock.testsupport.TestFiles.filePath;
-import static org.hamcrest.Matchers.*;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
 
 public class TransferEncodingAcceptanceTest {
 
@@ -116,10 +119,10 @@ public void sendsSpecifiedContentLengthInResponseWhenChunkedEncodingEnabled() th
 
         String path = "/length";
         wm.stubFor(get(path)
-            .willReturn(ok("stuff")
+            .willReturn(ok(StringUtils.repeat('a', 1234))
                     .withHeader("Content-Length", "1234")));
 
-        CloseableHttpClient httpClient = HttpClient4Factory.createClient();
+        CloseableHttpClient httpClient = HttpClientFactory.createClient();
         HttpGet request = new HttpGet(wm.baseUrl() + path);
         try (final CloseableHttpResponse response = httpClient.execute(request)) {
             assertThat(response.getFirstHeader("Content-Length").getValue(), is("1234"));
@@ -132,10 +135,10 @@ public void sendsSpecifiedContentLengthInResponseWhenChunkedEncodingDisabled() t
 
         String path = "/length";
         wm.stubFor(get(path)
-            .willReturn(ok("stuff")
+            .willReturn(ok(StringUtils.repeat('a', 1234))
                     .withHeader("Content-Length", "1234")));
 
-        CloseableHttpClient httpClient = HttpClient4Factory.createClient();
+        CloseableHttpClient httpClient = HttpClientFactory.createClient();
         HttpGet request = new HttpGet(wm.baseUrl() + path);
         try (CloseableHttpResponse response = httpClient.execute(request)) {
             assertThat(response.getFirstHeader("Content-Length").getValue(), is("1234"));
diff --git a/src/test/java/com/github/tomakehurst/wiremock/VerificationAcceptanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/VerificationAcceptanceTest.java
index a6e89fbc64..3fbf134219 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/VerificationAcceptanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/VerificationAcceptanceTest.java
@@ -29,7 +29,7 @@
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
 import com.github.tomakehurst.wiremock.verification.LoggedRequest;
 import com.github.tomakehurst.wiremock.verification.RequestJournalDisabledException;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -46,7 +46,7 @@
 import static com.github.tomakehurst.wiremock.testsupport.WireMatchers.findServeEventWithUrl;
 import static com.github.tomakehurst.wiremock.verification.diff.JUnitStyleDiffRenderer.junitStyleDiffMessage;
 import static java.lang.System.lineSeparator;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.Matchers.containsString;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/WireMockJUnitRuleTest.java b/src/test/java/com/github/tomakehurst/wiremock/WireMockJUnitRuleTest.java
index 9ef3affe04..b506a2939b 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/WireMockJUnitRuleTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/WireMockJUnitRuleTest.java
@@ -17,7 +17,7 @@
 
 import com.github.tomakehurst.wiremock.client.WireMock;
 import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.http.Request;
 import com.github.tomakehurst.wiremock.http.RequestListener;
 import com.github.tomakehurst.wiremock.http.Response;
@@ -26,9 +26,9 @@
 import com.github.tomakehurst.wiremock.junit.WireMockRule;
 import com.github.tomakehurst.wiremock.testsupport.Network;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.HttpResponse;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Rule;
@@ -41,9 +41,9 @@
 
 import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
 
 @RunWith(Enclosed.class)
 public class WireMockJUnitRuleTest {
@@ -287,12 +287,12 @@ public static class HttpsOnly {
         public void exposesHttpsOnly() throws Exception {
             wireMockRule.stubFor(any(anyUrl()).willReturn(ok()));
 
-            HttpClient client = HttpClient4Factory.createClient();
+            CloseableHttpClient client = HttpClientFactory.createClient();
 
             HttpGet request = new HttpGet("https://localhost:" + wireMockRule.httpsPort() + "/anything");
             HttpResponse response = client.execute(request);
 
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
     }
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/archunit/HttpClientTest.java b/src/test/java/com/github/tomakehurst/wiremock/archunit/HttpClientTest.java
index 160e9dcce6..0ac17f0a8c 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/archunit/HttpClientTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/archunit/HttpClientTest.java
@@ -22,7 +22,6 @@ class HttpClientTest {
 			.and().areNotAssignableTo(HttpAdminClient.class)
 			.and().areNotAssignableTo(HttpClientUtils.class)
 			.should().dependOnClassesThat().resideInAPackage("org.apache.hc..")
-			.orShould().dependOnClassesThat().resideInAPackage("org.apache.http..")
 			.as("Apache HttpClient should be limited to http package")
 			.because("we want to make the third party dependency optional");
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/common/HttpClient4Utils.java b/src/test/java/com/github/tomakehurst/wiremock/common/HttpClient4Utils.java
deleted file mode 100644
index c8a4557558..0000000000
--- a/src/test/java/com/github/tomakehurst/wiremock/common/HttpClient4Utils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Thomas Akehurst
- *
- * Licensed 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 com.github.tomakehurst.wiremock.common;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.util.EntityUtils;
-
-import java.io.IOException;
-
-import static com.google.common.base.Charsets.UTF_8;
-
-/**
- * Intended to facilitate the migration to Apache Http Client 5.x only; allows us to keep the test interfaces the same.
- */
-public class HttpClient4Utils {
-
-	public static String getEntityAsStringAndCloseStream(HttpResponse httpResponse) {
-		HttpEntity entity = httpResponse.getEntity();
-		if (entity != null) {
-			try {
-				String content = EntityUtils.toString(entity, UTF_8.name());
-				entity.getContent().close();
-				return content;
-			} catch (IOException ioe) {
-				throw new RuntimeException(ioe);
-			}
-		}
-		
-		return null;
-	}
-	
-	public static byte[] getEntityAsByteArrayAndCloseStream(HttpResponse httpResponse) {
-		HttpEntity entity = httpResponse.getEntity();
-		if (entity != null) {
-			try {
-				byte[] content = EntityUtils.toByteArray(entity);
-				entity.getContent().close();
-				return content;
-			} catch (IOException ioe) {
-				throw new RuntimeException(ioe);
-			}
-		}
-		
-		return null;
-	}
-}
diff --git a/src/test/java/com/github/tomakehurst/wiremock/http/AdminRequestHandlerTest.java b/src/test/java/com/github/tomakehurst/wiremock/http/AdminRequestHandlerTest.java
index a5d0e732dc..a7876f3c58 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/http/AdminRequestHandlerTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/http/AdminRequestHandlerTest.java
@@ -18,7 +18,7 @@
 import com.github.tomakehurst.wiremock.common.Notifier;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClient4Factory.java b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClient4Factory.java
deleted file mode 100644
index 133c94ef02..0000000000
--- a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClient4Factory.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2011 Thomas Akehurst
- *
- * Licensed 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 com.github.tomakehurst.wiremock.http;
-
-import com.github.tomakehurst.wiremock.common.ssl.KeyStoreSettings;
-import com.github.tomakehurst.wiremock.common.ProxySettings;
-import com.github.tomakehurst.wiremock.http.ssl.HostVerifyingSSLSocketFactory;
-import com.github.tomakehurst.wiremock.http.ssl.SSLContextBuilder;
-import com.github.tomakehurst.wiremock.http.ssl.TrustEverythingStrategy;
-import com.github.tomakehurst.wiremock.http.ssl.TrustSelfSignedStrategy;
-import com.github.tomakehurst.wiremock.http.ssl.TrustSpecificHostsStrategy;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.*;
-import org.apache.http.config.SocketConfig;
-import org.apache.http.conn.ConnectionKeepAliveStrategy;
-import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.impl.NoConnectionReuseStrategy;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.ProxyAuthenticationStrategy;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.util.TextUtils;
-
-import javax.net.ssl.SSLContext;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableEntryException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-
-import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
-import static com.github.tomakehurst.wiremock.common.ssl.KeyStoreSettings.NO_STORE;
-import static com.github.tomakehurst.wiremock.common.LocalNotifier.notifier;
-import static com.github.tomakehurst.wiremock.common.ProxySettings.NO_PROXY;
-import static com.github.tomakehurst.wiremock.http.RequestMethod.*;
-import static org.apache.commons.lang3.StringUtils.isEmpty;
-
-/**
- * Intended to facilitate the migration to Apache Http Client 5.x only; allows us to keep the test interfaces the same.
- */
-public class HttpClient4Factory {
-
-    public static final int DEFAULT_MAX_CONNECTIONS = 50;
-    public static final int DEFAULT_TIMEOUT = 30000;
-
-    private static final ConnectionKeepAliveStrategy NO_KEEP_ALIVE = new ConnectionKeepAliveStrategy() {
-        @Override
-        public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
-            return 0;
-        }
-    };
-
-    public static CloseableHttpClient createClient(
-            int maxConnections,
-            int timeoutMilliseconds,
-            ProxySettings proxySettings,
-            KeyStoreSettings trustStoreSettings,
-            boolean trustSelfSignedCertificates,
-            final List<String> trustedHosts,
-            boolean useSystemProperties) {
-
-        HttpClientBuilder builder = HttpClientBuilder.create()
-                .disableAuthCaching()
-                .disableAutomaticRetries()
-                .disableCookieManagement()
-                .disableRedirectHandling()
-                .disableContentCompression()
-                .setMaxConnTotal(maxConnections)
-                .setMaxConnPerRoute(maxConnections)
-                .setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build())
-                .setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(timeoutMilliseconds).build())
-                .setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE)
-                .setKeepAliveStrategy(NO_KEEP_ALIVE);
-
-        if (useSystemProperties) {
-            builder.useSystemProperties();
-        }
-
-        if (proxySettings != NO_PROXY) {
-            HttpHost proxyHost = new HttpHost(proxySettings.host(), proxySettings.port());
-            builder.setProxy(proxyHost);
-            if(!isEmpty(proxySettings.getUsername()) && !isEmpty(proxySettings.getPassword())) {
-                builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
-                BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
-                credentialsProvider.setCredentials(
-                        new AuthScope(proxySettings.host(), proxySettings.port()),
-                        new UsernamePasswordCredentials(proxySettings.getUsername(), proxySettings.getPassword()));
-                builder.setDefaultCredentialsProvider(credentialsProvider);
-            }
-        }
-
-        final SSLContext sslContext = buildSslContext(trustStoreSettings, trustSelfSignedCertificates, trustedHosts);
-        LayeredConnectionSocketFactory sslSocketFactory = buildSslConnectionSocketFactory(sslContext);
-        builder.setSSLSocketFactory(sslSocketFactory);
-
-        return builder.build();
-	}
-
-    private static LayeredConnectionSocketFactory buildSslConnectionSocketFactory(final SSLContext sslContext) {
-        final String[] supportedProtocols = split(System.getProperty("https.protocols"));
-        final String[] supportedCipherSuites = split(System.getProperty("https.cipherSuites"));
-
-        return new SSLConnectionSocketFactory(
-            new HostVerifyingSSLSocketFactory(sslContext.getSocketFactory()),
-            supportedProtocols,
-            supportedCipherSuites,
-            new NoopHostnameVerifier() // using Java's hostname verification
-        );
-    }
-
-    /**
-     * Copied from {@link HttpClientBuilder#split(String)} which is not
-     * the same as {@link org.apache.commons.lang3.StringUtils#split(String)}
-      */
-    private static String[] split(final String s) {
-        if (TextUtils.isBlank(s)) {
-            return null;
-        }
-        return s.split(" *, *");
-    }
-
-    private static SSLContext buildSslContext(
-        KeyStoreSettings trustStoreSettings,
-        boolean trustSelfSignedCertificates,
-        List<String> trustedHosts
-    ) {
-        if (trustStoreSettings != NO_STORE) {
-            return buildSSLContextWithTrustStore(trustStoreSettings, trustSelfSignedCertificates, trustedHosts);
-        } else if (trustSelfSignedCertificates) {
-            return buildAllowAnythingSSLContext();
-        } else {
-            try {
-                return SSLContextBuilder.create().loadTrustMaterial(new TrustSpecificHostsStrategy(trustedHosts)).build();
-            } catch (NoSuchAlgorithmException | KeyManagementException e) {
-                return throwUnchecked(e, null);
-            }
-        }
-    }
-
-    public static CloseableHttpClient createClient(
-            int maxConnections,
-            int timeoutMilliseconds,
-            ProxySettings proxySettings,
-            KeyStoreSettings trustStoreSettings,
-            boolean useSystemProperties) {
-        return createClient(maxConnections, timeoutMilliseconds, proxySettings, trustStoreSettings, true, Collections.<String>emptyList(), useSystemProperties);
-    }
-
-    private static SSLContext buildSSLContextWithTrustStore(KeyStoreSettings trustStoreSettings, boolean trustSelfSignedCertificates, List<String> trustedHosts) {
-        try {
-            KeyStore trustStore = trustStoreSettings.loadStore();
-            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create()
-                    .loadKeyMaterial(trustStore, trustStoreSettings.password().toCharArray());
-            if (trustSelfSignedCertificates) {
-                sslContextBuilder.loadTrustMaterial(new TrustSelfSignedStrategy());
-            } else if (containsCertificate(trustStore)) {
-                sslContextBuilder.loadTrustMaterial(trustStore, new TrustSpecificHostsStrategy(trustedHosts));
-            } else {
-                sslContextBuilder.loadTrustMaterial(new TrustSpecificHostsStrategy(trustedHosts));
-            }
-            return sslContextBuilder
-                    .build();
-        } catch (Exception e) {
-            return throwUnchecked(e, SSLContext.class);
-        }
-    }
-
-    private static boolean containsCertificate(KeyStore trustStore) throws KeyStoreException {
-        Enumeration<String> aliases = trustStore.aliases();
-        while (aliases.hasMoreElements()) {
-            String alias = aliases.nextElement();
-            try {
-                if (trustStore.getEntry(alias, null) instanceof KeyStore.TrustedCertificateEntry) {
-                    return true;
-                }
-            } catch (NoSuchAlgorithmException | UnrecoverableEntryException e) {
-                // ignore
-            }
-        }
-        return false;
-    }
-
-    private static SSLContext buildAllowAnythingSSLContext() {
-        try {
-            return SSLContextBuilder.create().loadTrustMaterial(new TrustEverythingStrategy()).build();
-        } catch (Exception e) {
-            return throwUnchecked(e, null);
-        }
-    }
-
-    public static CloseableHttpClient createClient(int maxConnections, int timeoutMilliseconds) {
-        return createClient(maxConnections, timeoutMilliseconds, NO_PROXY, NO_STORE, true);
-    }
-
-	public static CloseableHttpClient createClient(int timeoutMilliseconds) {
-		return createClient(DEFAULT_MAX_CONNECTIONS, timeoutMilliseconds);
-	}
-
-    public static CloseableHttpClient createClient(ProxySettings proxySettings) {
-        return createClient(DEFAULT_MAX_CONNECTIONS, DEFAULT_TIMEOUT, proxySettings, NO_STORE, true);
-    }
-
-    public static CloseableHttpClient createClient() {
-      return createClient(DEFAULT_TIMEOUT);
-    }
-
-    public static HttpUriRequest getHttpRequestFor(RequestMethod method, String url) {
-        notifier().info("Proxying: " + method + " " + url);
-
-        if (method.equals(GET))
-            return new HttpGet(url);
-        else if (method.equals(POST))
-            return new HttpPost(url);
-        else if (method.equals(PUT))
-            return new HttpPut(url);
-        else if (method.equals(DELETE))
-            return new HttpDelete(url);
-        else if (method.equals(HEAD))
-            return new HttpHead(url);
-        else if (method.equals(OPTIONS))
-            return new HttpOptions(url);
-        else if (method.equals(TRACE))
-            return new HttpTrace(url);
-        else if (method.equals(PATCH))
-            return new HttpPatch(url);
-        else
-            return new GenericHttpUriRequest(method.toString(), url);
-    }
-}
diff --git a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryAcceptsTrustedCertificatesTest.java b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryAcceptsTrustedCertificatesTest.java
index eae54a15e2..5cbef267e5 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryAcceptsTrustedCertificatesTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryAcceptsTrustedCertificatesTest.java
@@ -15,8 +15,8 @@
  */
 package com.github.tomakehurst.wiremock.http;
 
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
@@ -25,7 +25,7 @@
 
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.common.HttpClient4Utils.getEntityAsStringAndCloseStream;
+import static com.github.tomakehurst.wiremock.common.HttpClientUtils.getEntityAsStringAndCloseStream;
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -52,7 +52,7 @@ public void certificatesAreAccepted(List<String> trustedHosts, String certificat
 
         server.stubFor(get("/whatever").willReturn(aResponse().withBody("Hello World")));
 
-        HttpResponse response = client.execute(new HttpGet(server.url("/whatever")));
+        CloseableHttpResponse response = client.execute(new HttpGet(server.url("/whatever")));
 
         String result = getEntityAsStringAndCloseStream(response);
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryCertificateVerificationTest.java b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryCertificateVerificationTest.java
index 8ad04b54a3..69452aab32 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryCertificateVerificationTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryCertificateVerificationTest.java
@@ -21,7 +21,7 @@
 import com.github.tomakehurst.wiremock.crypto.InMemoryKeyStore;
 import com.github.tomakehurst.wiremock.crypto.Secret;
 import com.github.tomakehurst.wiremock.crypto.X509CertificateSpecification;
-import org.apache.http.client.HttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.junit.jupiter.api.AfterEach;
 
 import java.io.File;
@@ -43,7 +43,7 @@ public abstract class HttpClientFactoryCertificateVerificationTest {
     protected static final List<String> TRUST_NOBODY = emptyList();
 
     protected WireMockServer server = null;
-    protected HttpClient client;
+    protected CloseableHttpClient client;
 
     public void startServerAndBuildClient(
             List<String> trustedHosts,
@@ -86,7 +86,7 @@ public void startServerAndBuildClient(
         clientTrustStore.saveAs(clientTrustStoreFile);
         KeyStoreSettings clientTrustStoreSettings = new KeyStoreSettings(clientTrustStoreFile.getAbsolutePath(), "password", "jks");
 
-        client = HttpClient4Factory.createClient(
+        client = HttpClientFactory.createClient(
                 1000,
                 5 * 1000 * 60,
                 NO_PROXY,
diff --git a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryRejectsUntrustedCertificatesTest.java b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryRejectsUntrustedCertificatesTest.java
index e8362abd56..ce03c429e5 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryRejectsUntrustedCertificatesTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/http/HttpClientFactoryRejectsUntrustedCertificatesTest.java
@@ -15,7 +15,7 @@
  */
 package com.github.tomakehurst.wiremock.http;
 
-import org.apache.http.client.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeTest.java
index 3d632777bc..6b14e90cf9 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeTest.java
@@ -16,10 +16,10 @@
 package com.github.tomakehurst.wiremock.junit5;
 
 import com.github.tomakehurst.wiremock.client.WireMock;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -36,7 +36,7 @@ public class JUnitJupiterExtensionDeclarativeTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
@@ -50,13 +50,13 @@ void provides_wiremock_info_as_method_parameter(WireMockRuntimeInfo wmRuntimeInf
         wireMock.register(get("/instance-dsl").willReturn(ok()));
         HttpGet request = new HttpGet(wmRuntimeInfo.getHttpBaseUrl() + "/instance-dsl");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
 
         stubFor(get("/static-dsl").willReturn(ok()));
         request = new HttpGet(wmRuntimeInfo.getHttpBaseUrl() + "/static-dsl");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
     }
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeWithRandomHttpsPortParameterTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeWithRandomHttpsPortParameterTest.java
index 180aaee62a..9a92deb223 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeWithRandomHttpsPortParameterTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionDeclarativeWithRandomHttpsPortParameterTest.java
@@ -15,10 +15,10 @@
  */
 package com.github.tomakehurst.wiremock.junit5;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -34,7 +34,7 @@ public class JUnitJupiterExtensionDeclarativeWithRandomHttpsPortParameterTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
@@ -45,7 +45,7 @@ void runs_on_a_random_port_when_enabled(WireMockRuntimeInfo wmRuntimeInfo) throw
 
         HttpGet request = new HttpGet(wmRuntimeInfo.getHttpsBaseUrl() + "/thing");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
     }
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionFailOnUnmatchedTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionFailOnUnmatchedTest.java
index 5004bb4a5a..56e8080030 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionFailOnUnmatchedTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionFailOnUnmatchedTest.java
@@ -16,10 +16,10 @@
 package com.github.tomakehurst.wiremock.junit5;
 
 import com.github.tomakehurst.wiremock.client.VerificationException;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtensionContext;
@@ -42,7 +42,7 @@ public class JUnitJupiterExtensionFailOnUnmatchedTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
 
         extensionContext = Mockito.mock(ExtensionContext.class);
         when(extensionContext.getElement()).thenReturn(Optional.empty());
@@ -59,7 +59,7 @@ void throws_a_verification_exception_when_an_unmatched_request_is_made_during_th
         extension.stubFor(get("/found").willReturn(ok()));
 
         try (CloseableHttpResponse response = client.execute(new HttpGet(extension.url("/not-found")))) {
-            assertThat(response.getStatusLine().getStatusCode(), is(404));
+            assertThat(response.getCode(), is(404));
         }
 
         assertThrows(VerificationException.class, () -> extension.afterEach(extensionContext));
@@ -76,7 +76,7 @@ void does_not_throw_a_verification_exception_when_fail_on_unmatched_disabled() t
         extension.stubFor(get("/found").willReturn(ok()));
 
         try (CloseableHttpResponse response = client.execute(new HttpGet(extension.url("/not-found")))) {
-            assertThat(response.getStatusLine().getStatusCode(), is(404));
+            assertThat(response.getCode(), is(404));
         }
 
         assertDoesNotThrow(() -> extension.afterEach(extensionContext));
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyDeclarativeTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyDeclarativeTest.java
index f448d1e02d..9b350b50da 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyDeclarativeTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyDeclarativeTest.java
@@ -1,14 +1,17 @@
 package com.github.tomakehurst.wiremock.junit5;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 
@@ -19,7 +22,7 @@ public class JUnitJupiterExtensionJvmProxyDeclarativeTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyNonStaticProgrammaticTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyNonStaticProgrammaticTest.java
index 6e00a4dfda..475d9fa91b 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyNonStaticProgrammaticTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyNonStaticProgrammaticTest.java
@@ -1,15 +1,18 @@
 package com.github.tomakehurst.wiremock.junit5;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -27,7 +30,7 @@ public class JUnitJupiterExtensionJvmProxyNonStaticProgrammaticTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyStaticProgrammaticTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyStaticProgrammaticTest.java
index ba6665aefd..04af5011a7 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyStaticProgrammaticTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionJvmProxyStaticProgrammaticTest.java
@@ -1,15 +1,18 @@
 package com.github.tomakehurst.wiremock.junit5;
 
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -27,7 +30,7 @@ public class JUnitJupiterExtensionJvmProxyStaticProgrammaticTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionNonStaticMultiInstanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionNonStaticMultiInstanceTest.java
index 7652550443..369df560bf 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionNonStaticMultiInstanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionNonStaticMultiInstanceTest.java
@@ -16,11 +16,11 @@
 package com.github.tomakehurst.wiremock.junit5;
 
 import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
 import org.junit.jupiter.api.Order;
@@ -28,7 +28,10 @@
 import org.junit.jupiter.api.TestMethodOrder;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getAllServeEvents;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -53,7 +56,7 @@ public class JUnitJupiterExtensionNonStaticMultiInstanceTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
@@ -65,14 +68,14 @@ void extension_field_provides_wiremock_info() throws Exception {
         stubFor(get("/wm1").willReturn(ok()));
         HttpGet request = new HttpGet(wm1RuntimeInfo.getHttpsBaseUrl() + "/wm1");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
 
         WireMockRuntimeInfo wm2RuntimeInfo = wm2.getRuntimeInfo();
         wm2.stubFor(get("/wm2").willReturn(ok("{{request.path.0}}")));
         request = new HttpGet(wm2RuntimeInfo.getHttpBaseUrl() + "/wm2");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
             assertThat(EntityUtils.toString(response.getEntity()), is("wm2")); // Ensures templating is enabled
         }
     }
@@ -86,7 +89,7 @@ void wiremock_is_reset_between_tests() throws Exception {
 
         HttpGet request = new HttpGet(wm1RuntimeInfo.getHttpsBaseUrl() + "/wm1");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(404));
+            assertThat(response.getCode(), is(404));
         }
     }
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionStaticMultiInstanceTest.java b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionStaticMultiInstanceTest.java
index 7e18d93d99..eb85abd3ac 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionStaticMultiInstanceTest.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/junit5/JUnitJupiterExtensionStaticMultiInstanceTest.java
@@ -16,11 +16,11 @@
 package com.github.tomakehurst.wiremock.junit5;
 
 import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.util.EntityUtils;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
 import org.junit.jupiter.api.Order;
@@ -28,7 +28,10 @@
 import org.junit.jupiter.api.TestMethodOrder;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.getAllServeEvents;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -53,7 +56,7 @@ public class JUnitJupiterExtensionStaticMultiInstanceTest {
 
     @BeforeEach
     void init() {
-        client = HttpClient4Factory.createClient();
+        client = HttpClientFactory.createClient();
     }
 
     @Test
@@ -65,14 +68,14 @@ void extension_field_provides_wiremock_info() throws Exception {
         stubFor(get("/wm1").willReturn(ok()));
         HttpGet request = new HttpGet(wm1RuntimeInfo.getHttpsBaseUrl() + "/wm1");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
         }
 
         WireMockRuntimeInfo wm2RuntimeInfo = wm2.getRuntimeInfo();
         wm2.stubFor(get("/wm2").willReturn(ok("{{request.path.0}}")));
         request = new HttpGet(wm2RuntimeInfo.getHttpBaseUrl() + "/wm2");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(200));
+            assertThat(response.getCode(), is(200));
             assertThat(EntityUtils.toString(response.getEntity()), is("wm2")); // Ensures templating is enabled
         }
     }
@@ -86,7 +89,7 @@ void wiremock_is_reset_between_tests() throws Exception {
 
         HttpGet request = new HttpGet(wm1RuntimeInfo.getHttpsBaseUrl() + "/wm1");
         try (CloseableHttpResponse response = client.execute(request)) {
-            assertThat(response.getStatusLine().getStatusCode(), is(404));
+            assertThat(response.getCode(), is(404));
         }
     }
 
diff --git a/src/test/java/com/github/tomakehurst/wiremock/testsupport/MultipartBody.java b/src/test/java/com/github/tomakehurst/wiremock/testsupport/MultipartBody.java
index 48c7bdbd01..c183eb6648 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/testsupport/MultipartBody.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/testsupport/MultipartBody.java
@@ -30,11 +30,12 @@
  */
 package com.github.tomakehurst.wiremock.testsupport;
 
+import org.apache.hc.client5.http.entity.mime.AbstractContentBody;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.util.Args;
+
 import java.io.IOException;
 import java.io.OutputStream;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.mime.content.AbstractContentBody;
-import org.apache.http.util.Args;
 
 import static com.github.tomakehurst.wiremock.common.Strings.bytesFromString;
 
@@ -76,11 +77,6 @@ public void writeTo(OutputStream out) throws IOException {
         out.write(body);
     }
 
-    @Override
-    public String getTransferEncoding() {
-        return "7bit";
-    }
-
     @Override
     public long getContentLength() {
         return body.length;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMatchers.java b/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMatchers.java
index f208d069f9..c64c2ec6f3 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMatchers.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMatchers.java
@@ -17,19 +17,18 @@
 
 import com.github.tomakehurst.wiremock.common.TextFile;
 import com.github.tomakehurst.wiremock.http.HttpHeader;
-import com.github.tomakehurst.wiremock.matching.EqualToXmlPattern;
 import com.github.tomakehurst.wiremock.matching.UrlPattern;
 import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
 import com.github.tomakehurst.wiremock.stubbing.StubMapping;
-import com.google.common.base.Charsets;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.hamcrest.*;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.hamcrest.TypeSafeMatcher;
 import org.hamcrest.core.IsEqual;
 import org.skyscreamer.jsonassert.JSONAssert;
 import org.skyscreamer.jsonassert.JSONCompareMode;
diff --git a/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockResponse.java b/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockResponse.java
index 4c8d9c7ee9..3ad82a5bb9 100644
--- a/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockResponse.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockResponse.java
@@ -17,55 +17,55 @@
 
 import com.google.common.collect.ImmutableListMultimap;
 import com.google.common.collect.Multimap;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.Header;
 
 import java.nio.charset.Charset;
 
-import static com.github.tomakehurst.wiremock.common.HttpClient4Utils.getEntityAsByteArrayAndCloseStream;
+import static com.github.tomakehurst.wiremock.common.HttpClientUtils.getEntityAsByteArrayAndCloseStream;
 import static com.google.common.base.Charsets.UTF_8;
 import static com.google.common.collect.Iterables.getFirst;
 
 public class WireMockResponse {
-	
-	private final HttpResponse httpResponse;
+
+	private final ClassicHttpResponse httpResponse;
 	private final byte[] content;
-	
-	public WireMockResponse(HttpResponse httpResponse) {
+
+	public WireMockResponse(ClassicHttpResponse httpResponse) {
 		this.httpResponse = httpResponse;
 		content = getEntityAsByteArrayAndCloseStream(httpResponse);
 	}
 
 	public int statusCode() {
-		return httpResponse.getStatusLine().getStatusCode();
+		return httpResponse.getCode();
 	}
-	
+
 	public String content() {
-        if(content==null) {
-            return null;
-        }
+		if (content == null) {
+			return null;
+		}
 		return new String(content, Charset.forName(UTF_8.name()));
 	}
 
-    public byte[] binaryContent() {
-        return content;
-    }
-	
+	public byte[] binaryContent() {
+		return content;
+	}
+
 	public String firstHeader(String key) {
 		return getFirst(headers().get(key), null);
 	}
-	
+
 	public Multimap<String, String> headers() {
-        ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
+		ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
 
-		for (Header header: httpResponse.getAllHeaders()) {
+		for (Header header : httpResponse.getHeaders()) {
 			builder.put(header.getName(), header.getValue());
 		}
-		
+
 		return builder.build();
 	}
 
 	public String statusMessage() {
-		return httpResponse.getStatusLine().getReasonPhrase();
+		return httpResponse.getReasonPhrase();
 	}
 }
diff --git a/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockTestClient.java b/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockTestClient.java
index 76b48b656a..9d53a117f3 100755
--- a/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockTestClient.java
+++ b/src/test/java/com/github/tomakehurst/wiremock/testsupport/WireMockTestClient.java
@@ -15,51 +15,50 @@
  */
 package com.github.tomakehurst.wiremock.testsupport;
 
-import com.github.tomakehurst.wiremock.http.GenericHttpUriRequest;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.AuthCache;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.*;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.ssl.SSLContexts;
-import org.apache.http.ssl.TrustStrategy;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.classic.methods.*;
+import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.ssl.TrustStrategy;
 
-import javax.net.ssl.SSLContext;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.URI;
 import java.security.cert.X509Certificate;
 import java.util.Collection;
 
+import javax.net.ssl.SSLContext;
+
 import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
 import static com.github.tomakehurst.wiremock.http.MimeType.JSON;
 import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.net.HttpURLConnection.*;
-import static org.apache.http.entity.ContentType.APPLICATION_JSON;
-import static org.apache.http.entity.ContentType.APPLICATION_XML;
+import static java.net.HttpURLConnection.HTTP_CREATED;
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_JSON;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_XML;
+import static org.apache.hc.core5.http.ContentType.DEFAULT_BINARY;
 
 public class WireMockTestClient {
 
     private static final String LOCAL_WIREMOCK_ROOT = "http://%s:%d%s";
     private static final String LOCAL_WIREMOCK_NEW_RESPONSE_URL = "http://%s:%d/__admin/mappings/new";
-    private static final String LOCAL_WIREMOCK_REMOVE_RESPONSE_URL = "http://%s:%d/__admin/mappings/remove";
     private static final String LOCAL_WIREMOCK_EDIT_RESPONSE_URL = "http://%s:%d/__admin/mappings/edit";
-    private static final String LOCAL_WIREMOCK_RESET_URL = "http://%s:%d/__admin/reset";
     private static final String LOCAL_WIREMOCK_RESET_DEFAULT_MAPPINS_URL = "http://%s:%d/__admin/mappings/reset";
     private static final String LOCAL_WIREMOCK_SNAPSHOT_PATH = "/__admin/recordings/snapshot";
 
@@ -106,30 +105,34 @@ public WireMockResponse getViaProxy(String url) {
     }
 
     public WireMockResponse getViaProxy(String url, int proxyPort) {
-        return getViaProxy(url, proxyPort, HttpHost.DEFAULT_SCHEME_NAME);
+        return getViaProxy(url, proxyPort, HttpHost.DEFAULT_SCHEME.getId());
     }
 
     public WireMockResponse getViaProxy(String url, int proxyPort, String scheme) {
         URI targetUri = URI.create(url);
-        HttpHost proxy = new HttpHost(address, proxyPort, scheme);
+        HttpHost proxy = new HttpHost(scheme, address, proxyPort);
         HttpClient httpClientUsingProxy = HttpClientBuilder.create()
             .disableAuthCaching()
             .disableAutomaticRetries()
             .disableCookieManagement()
             .disableRedirectHandling()
-            .setSSLContext(buildTrustWireMockDefaultCertificateSSLContext())
-            .setSSLHostnameVerifier(new NoopHostnameVerifier())
+            .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
+                    .setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
+                            .setSslContext(buildTrustWireMockDefaultCertificateSSLContext())
+                            .setHostnameVerifier(new NoopHostnameVerifier())
+                            .build())
+                    .build())
             .setProxy(proxy)
             .build();
 
         try {
-            HttpHost target = new HttpHost(targetUri.getHost(), targetUri.getPort(), targetUri.getScheme());
+            HttpHost target = new HttpHost(targetUri.getScheme(), targetUri.getHost(), targetUri.getPort());
             HttpGet req = new HttpGet(targetUri.getPath() +
                 (isNullOrEmpty(targetUri.getQuery()) ? "" : "?" + targetUri.getQuery()));
             req.removeHeaders("Host");
 
             System.out.println("executing request to " + targetUri + "(" + target + ") via " + proxy);
-            HttpResponse httpResponse = httpClientUsingProxy.execute(target, req);
+            ClassicHttpResponse httpResponse = httpClientUsingProxy.execute(target, req);
             return new WireMockResponse(httpResponse);
         } catch (IOException ioe) {
             throw new RuntimeException(ioe);
@@ -152,7 +155,7 @@ public WireMockResponse patchWithBody(String url, String body, String contentTyp
     }
 
     private WireMockResponse requestWithBody(
-        HttpEntityEnclosingRequestBase request, String body, String contentType, TestHttpHeader... headers) {
+            HttpUriRequestBase request, String body, String contentType, TestHttpHeader... headers) {
         request.setEntity(new StringEntity(body, ContentType.create(contentType, "utf-8")));
         return executeMethodAndConvertExceptions(request, headers);
     }
@@ -174,7 +177,7 @@ public WireMockResponse postWithMultiparts(String url, Collection<MultipartBody>
     }
 
     public WireMockResponse postWithChunkedBody(String url, byte[] body) {
-        return post(url, new InputStreamEntity(new ByteArrayInputStream(body), -1));
+        return post(url, new InputStreamEntity(new ByteArrayInputStream(body), -1, DEFAULT_BINARY));
     }
 
     public WireMockResponse post(String url, HttpEntity entity, TestHttpHeader... headers) {
@@ -258,8 +261,8 @@ private int postJsonAndReturnStatus(String url, String json, String charset) {
             if (json != null) {
                 post.setEntity(new StringEntity(json, ContentType.create(JSON.toString(), charset)));
             }
-            HttpResponse httpResponse = httpClient().execute(post);
-            return httpResponse.getStatusLine().getStatusCode();
+            ClassicHttpResponse httpResponse = httpClient().execute(post);
+            return httpResponse.getCode();
         } catch (RuntimeException re) {
             throw re;
         } catch (Exception e) {
@@ -276,7 +279,7 @@ private WireMockResponse executeMethodAndConvertExceptions(HttpUriRequest httpRe
             for (TestHttpHeader header : headers) {
                 httpRequest.addHeader(header.getName(), header.getValue());
             }
-            HttpResponse httpResponse = httpClient().execute(httpRequest);
+            ClassicHttpResponse httpResponse = httpClient().execute(httpRequest);
             return new WireMockResponse(httpResponse);
         } catch (IOException ioe) {
             throw new RuntimeException(ioe);
@@ -284,18 +287,18 @@ private WireMockResponse executeMethodAndConvertExceptions(HttpUriRequest httpRe
     }
 
     public WireMockResponse getWithPreemptiveCredentials(String url, int port, String username, String password) {
-        HttpHost target = new HttpHost("localhost", port);
-        HttpClient httpClient = httpClientWithPreemptiveAuth(target, username, password);
+        CloseableHttpClient httpClient = HttpClients.createDefault();
 
-        AuthCache authCache = new BasicAuthCache();
         BasicScheme basicAuth = new BasicScheme();
-        authCache.put(target, basicAuth);
+        basicAuth.initPreemptive(new UsernamePasswordCredentials(username, password.toCharArray()));
+
         HttpClientContext localContext = HttpClientContext.create();
-        localContext.setAuthCache(authCache);
+        HttpHost target = new HttpHost("localhost", port);
+        localContext.resetAuthExchange(target, basicAuth);
 
         try {
             HttpGet httpget = new HttpGet(url);
-            HttpResponse response = httpClient.execute(target, httpget, localContext);
+            ClassicHttpResponse response = httpClient.execute(target, httpget, localContext);
             return new WireMockResponse(response);
         } catch (IOException e) {
             return throwUnchecked(e, WireMockResponse.class);
@@ -303,11 +306,11 @@ public WireMockResponse getWithPreemptiveCredentials(String url, int port, Strin
     }
 
     public WireMockResponse request(final String methodName, String url, TestHttpHeader... headers) {
-        HttpUriRequest httpRequest = new GenericHttpUriRequest(methodName, mockServiceUrlFor(url));
+        HttpUriRequest httpRequest = new HttpUriRequestBase(methodName, URI.create(mockServiceUrlFor(url)));
         return executeMethodAndConvertExceptions(httpRequest, headers);
     }
 
-    private static HttpClient httpClient() {
+    private static CloseableHttpClient httpClient() {
         return HttpClientBuilder.create()
             .disableAuthCaching()
             .disableAutomaticRetries()
@@ -317,17 +320,6 @@ private static HttpClient httpClient() {
             .build();
     }
 
-    private static HttpClient httpClientWithPreemptiveAuth(HttpHost target, String username, String password) {
-        CredentialsProvider credsProvider = new BasicCredentialsProvider();
-        credsProvider.setCredentials(
-            new AuthScope(target),
-            new UsernamePasswordCredentials(username, password));
-
-        return HttpClients.custom()
-            .setDefaultCredentialsProvider(credsProvider)
-            .build();
-    }
-
     private static SSLContext buildTrustWireMockDefaultCertificateSSLContext() {
         try {
             return SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
diff --git a/src/test/java/ignored/JUnit5ProxyTest.java b/src/test/java/ignored/JUnit5ProxyTest.java
index a572d4f032..b2cd7d13a4 100644
--- a/src/test/java/ignored/JUnit5ProxyTest.java
+++ b/src/test/java/ignored/JUnit5ProxyTest.java
@@ -3,17 +3,19 @@
 import com.github.tomakehurst.wiremock.WireMockServer;
 import com.github.tomakehurst.wiremock.http.JvmProxyConfigurer;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.ok;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
@@ -22,7 +24,7 @@ public class JUnit5ProxyTest {
     @RegisterExtension
     public WireMockExtension wm = WireMockExtension.newInstance().options(options().dynamicPort().enableBrowserProxying(true)).build();
 
-    HttpClient httpClient = HttpClientBuilder.create()
+    CloseableHttpClient httpClient = HttpClientBuilder.create()
             .useSystemProperties() // This must be enabled for auto-configuration of proxy settings to work
             .build();
 
@@ -46,7 +48,7 @@ public void testViaProxyUsingRule() throws Exception {
                 .withHost(equalTo("my.second.domain"))
                 .willReturn(ok("Domain 2")));
 
-        HttpResponse response = httpClient.execute(new HttpGet("http://my.first.domain/things"));
+        ClassicHttpResponse response = httpClient.execute(new HttpGet("http://my.first.domain/things"));
         String responseBody = EntityUtils.toString(response.getEntity());
         assertEquals("Domain 1", responseBody);
 
@@ -69,7 +71,7 @@ public void testViaProxyUsingServer() throws Exception {
                 .withHost(equalTo("my.second.domain"))
                 .willReturn(ok("Domain 2")));
 
-        HttpResponse response = httpClient.execute(new HttpGet("http://my.first.domain/things"));
+        ClassicHttpResponse response = httpClient.execute(new HttpGet("http://my.first.domain/things"));
         String responseBody = EntityUtils.toString(response.getEntity());
         assertEquals("Domain 1", responseBody);
 
diff --git a/src/test/java/ignored/NearMissExampleTest.java b/src/test/java/ignored/NearMissExampleTest.java
index 3fb6ad68da..1dc4d230c0 100644
--- a/src/test/java/ignored/NearMissExampleTest.java
+++ b/src/test/java/ignored/NearMissExampleTest.java
@@ -18,22 +18,15 @@
 import com.github.tomakehurst.wiremock.client.BasicCredentials;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import com.github.tomakehurst.wiremock.testsupport.WireMockTestClient;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.containing;
-import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
-import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.matching;
-import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
 import static com.github.tomakehurst.wiremock.testsupport.TestHttpHeader.withHeader;
-import static org.apache.http.entity.ContentType.APPLICATION_JSON;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_JSON;
 
 public class NearMissExampleTest {
 
diff --git a/src/test/java/ignored/VeryLongAsynchronousDelayAcceptanceTest.java b/src/test/java/ignored/VeryLongAsynchronousDelayAcceptanceTest.java
index 0f7361ef3e..0a70333e9a 100644
--- a/src/test/java/ignored/VeryLongAsynchronousDelayAcceptanceTest.java
+++ b/src/test/java/ignored/VeryLongAsynchronousDelayAcceptanceTest.java
@@ -17,13 +17,14 @@
 
 import com.github.tomakehurst.wiremock.common.Json;
 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
-import com.github.tomakehurst.wiremock.http.HttpClient4Factory;
+import com.github.tomakehurst.wiremock.http.HttpClientFactory;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import com.github.tomakehurst.wiremock.stubbing.StubMapping;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.RequestBuilder;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.ParseException;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 
@@ -48,19 +49,19 @@ private WireMockConfiguration getOptions() {
 
 
     @Test
-    public void longDelayWithBodyMatch() throws IOException {
+    public void longDelayWithBodyMatch() throws IOException, ParseException {
         String json = "{ \"id\": \"cb7872bd-89cd-4015-97d1-718779df7dfe\", \"priority\": 1, \"request\": { \"urlPattern\": \"/faulty.*/.*/path/path\", \"method\": \"POST\", \"bodyPatterns\": [ { \"matches\": \".*<xml>permissions</xml>.*\" } ] }, \"response\": { \"status\": 200, \"bodyFileName\": \"plain-example.txt\", \"fixedDelayMilliseconds\": 35000 } }\n";
 
         wireMockRule.addStubMapping(Json.read(json, StubMapping.class));
 
-        CloseableHttpResponse response = HttpClient4Factory.createClient(50, 120000)
-            .execute(RequestBuilder
+        CloseableHttpResponse response = HttpClientFactory.createClient(50, 120000)
+            .execute(ClassicRequestBuilder
             .post(wireMockRule.url("/faulty/1/path/path"))
             .setEntity(new StringEntity("<xml>permissions</xml>"))
             .build()
         );
 
-        assertThat(response.getStatusLine().getStatusCode(), is(200));
+        assertThat(response.getCode(), is(200));
         assertThat(EntityUtils.toString(response.getEntity()), is("Some example test from a file"));
     }
 
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
index 306ddc490f..30f15e6548 100644
--- a/src/test/resources/log4j.properties
+++ b/src/test/resources/log4j.properties
@@ -5,6 +5,6 @@ log4j.appender.stdout.target=System.out
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
 
-log4j.logger.org.apache.http.wire=DEBUG
+log4j.logger.org.apache.hc.client5.http.wire=DEBUG
 log4j.logger.org.eclipse.jetty.util.thread=WARN
 log4j.logger.org.eclipse.jetty.util.component=WARN
\ No newline at end of file
diff --git a/wiremock-webhooks-extension/src/test/java/com/github/tomakehurst/wiremock/common/HttpClient4Utils.java b/wiremock-webhooks-extension/src/test/java/com/github/tomakehurst/wiremock/common/HttpClient4Utils.java
deleted file mode 100644
index c8a4557558..0000000000
--- a/wiremock-webhooks-extension/src/test/java/com/github/tomakehurst/wiremock/common/HttpClient4Utils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Thomas Akehurst
- *
- * Licensed 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 com.github.tomakehurst.wiremock.common;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.util.EntityUtils;
-
-import java.io.IOException;
-
-import static com.google.common.base.Charsets.UTF_8;
-
-/**
- * Intended to facilitate the migration to Apache Http Client 5.x only; allows us to keep the test interfaces the same.
- */
-public class HttpClient4Utils {
-
-	public static String getEntityAsStringAndCloseStream(HttpResponse httpResponse) {
-		HttpEntity entity = httpResponse.getEntity();
-		if (entity != null) {
-			try {
-				String content = EntityUtils.toString(entity, UTF_8.name());
-				entity.getContent().close();
-				return content;
-			} catch (IOException ioe) {
-				throw new RuntimeException(ioe);
-			}
-		}
-		
-		return null;
-	}
-	
-	public static byte[] getEntityAsByteArrayAndCloseStream(HttpResponse httpResponse) {
-		HttpEntity entity = httpResponse.getEntity();
-		if (entity != null) {
-			try {
-				byte[] content = EntityUtils.toByteArray(entity);
-				entity.getContent().close();
-				return content;
-			} catch (IOException ioe) {
-				throw new RuntimeException(ioe);
-			}
-		}
-		
-		return null;
-	}
-}
diff --git a/wiremock-webhooks-extension/src/test/java/functional/FailingWebhookTest.java b/wiremock-webhooks-extension/src/test/java/functional/FailingWebhookTest.java
index 3ecb0f700f..ae542ea94b 100644
--- a/wiremock-webhooks-extension/src/test/java/functional/FailingWebhookTest.java
+++ b/wiremock-webhooks-extension/src/test/java/functional/FailingWebhookTest.java
@@ -3,7 +3,7 @@
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
 import static com.github.tomakehurst.wiremock.http.RequestMethod.POST;
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.wiremock.webhooks.Webhooks.webhook;
@@ -12,7 +12,7 @@
 import com.github.tomakehurst.wiremock.extension.PostServeAction;
 import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
 import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -27,7 +27,7 @@
 import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
 import static com.github.tomakehurst.wiremock.http.RequestMethod.POST;
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.wiremock.webhooks.Webhooks.webhook;
diff --git a/wiremock-webhooks-extension/src/test/java/functional/WebhooksAcceptanceTest.java b/wiremock-webhooks-extension/src/test/java/functional/WebhooksAcceptanceTest.java
index cbb282b94b..85d02688ed 100644
--- a/wiremock-webhooks-extension/src/test/java/functional/WebhooksAcceptanceTest.java
+++ b/wiremock-webhooks-extension/src/test/java/functional/WebhooksAcceptanceTest.java
@@ -9,7 +9,7 @@
 import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
 import com.github.tomakehurst.wiremock.verification.LoggedRequest;
 import com.google.common.base.Stopwatch;
-import org.apache.http.entity.StringEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -29,7 +29,7 @@
 import static com.github.tomakehurst.wiremock.http.RequestMethod.POST;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.apache.http.entity.ContentType.TEXT_PLAIN;
+import static org.apache.hc.core5.http.ContentType.TEXT_PLAIN;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
 import static org.junit.jupiter.api.Assertions.assertTrue;
diff --git a/wiremock-webhooks-extension/src/test/java/testsupport/WireMockResponse.java b/wiremock-webhooks-extension/src/test/java/testsupport/WireMockResponse.java
index 26ea8c0908..1584cc3988 100644
--- a/wiremock-webhooks-extension/src/test/java/testsupport/WireMockResponse.java
+++ b/wiremock-webhooks-extension/src/test/java/testsupport/WireMockResponse.java
@@ -17,48 +17,48 @@
 
 import com.google.common.collect.ImmutableListMultimap;
 import com.google.common.collect.Multimap;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.Header;
 
 import java.nio.charset.Charset;
 
-import static com.github.tomakehurst.wiremock.common.HttpClient4Utils.getEntityAsByteArrayAndCloseStream;
+import static com.github.tomakehurst.wiremock.common.HttpClientUtils.getEntityAsByteArrayAndCloseStream;
 import static com.google.common.base.Charsets.UTF_8;
 import static com.google.common.collect.Iterables.getFirst;
 
 public class WireMockResponse {
 
-	private final HttpResponse httpResponse;
+	private final ClassicHttpResponse httpResponse;
 	private final byte[] content;
 
-	public WireMockResponse(HttpResponse httpResponse) {
+	public WireMockResponse(ClassicHttpResponse httpResponse) {
 		this.httpResponse = httpResponse;
 		content = getEntityAsByteArrayAndCloseStream(httpResponse);
 	}
 
 	public int statusCode() {
-		return httpResponse.getStatusLine().getStatusCode();
+		return httpResponse.getCode();
 	}
 
 	public String content() {
-        if(content==null) {
-            return null;
-        }
+		if (content == null) {
+			return null;
+		}
 		return new String(content, Charset.forName(UTF_8.name()));
 	}
 
-    public byte[] binaryContent() {
-        return content;
-    }
+	public byte[] binaryContent() {
+		return content;
+	}
 
 	public String firstHeader(String key) {
 		return getFirst(headers().get(key), null);
 	}
 
 	public Multimap<String, String> headers() {
-        ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
+		ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
 
-		for (Header header: httpResponse.getAllHeaders()) {
+		for (Header header : httpResponse.getHeaders()) {
 			builder.put(header.getName(), header.getValue());
 		}
 
@@ -66,6 +66,6 @@ public Multimap<String, String> headers() {
 	}
 
 	public String statusMessage() {
-		return httpResponse.getStatusLine().getReasonPhrase();
+		return httpResponse.getReasonPhrase();
 	}
 }
diff --git a/wiremock-webhooks-extension/src/test/java/testsupport/WireMockTestClient.java b/wiremock-webhooks-extension/src/test/java/testsupport/WireMockTestClient.java
index e1c99feb85..650465b72f 100755
--- a/wiremock-webhooks-extension/src/test/java/testsupport/WireMockTestClient.java
+++ b/wiremock-webhooks-extension/src/test/java/testsupport/WireMockTestClient.java
@@ -15,25 +15,23 @@
  */
 package testsupport;
 
-import com.github.tomakehurst.wiremock.http.GenericHttpUriRequest;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.AuthCache;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.*;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.BasicAuthCache;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
+import org.apache.hc.client5.http.auth.AuthCache;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.methods.*;
+import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.apache.hc.core5.http.io.entity.StringEntity;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -42,14 +40,15 @@
 import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
 import static com.github.tomakehurst.wiremock.http.MimeType.JSON;
 import static com.google.common.base.Strings.isNullOrEmpty;
-import static java.net.HttpURLConnection.*;
-import static org.apache.http.entity.ContentType.APPLICATION_JSON;
+import static java.net.HttpURLConnection.HTTP_CREATED;
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_JSON;
 
 public class WireMockTestClient {
 
     private static final String LOCAL_WIREMOCK_ROOT = "http://%s:%d%s";
     private static final String LOCAL_WIREMOCK_NEW_RESPONSE_URL = "http://%s:%d/__admin/mappings/new";
-    private static final String LOCAL_WIREMOCK_REMOVE_RESPONSE_URL = "http://%s:%d/__admin/mappings/remove";
     private static final String LOCAL_WIREMOCK_EDIT_RESPONSE_URL = "http://%s:%d/__admin/mappings/edit";
     private static final String LOCAL_WIREMOCK_RESET_URL = "http://%s:%d/__admin/reset";
     private static final String LOCAL_WIREMOCK_RESET_DEFAULT_MAPPINS_URL = "http://%s:%d/__admin/mappings/reset";
@@ -70,8 +69,8 @@ public WireMockTestClient() {
         this(8080);
     }
 
-    private String mockServiceUrlFor(String path) {
-        return String.format(LOCAL_WIREMOCK_ROOT, address, port, path);
+    private URI mockServiceUrlFor(String path) {
+        return URI.create(String.format(LOCAL_WIREMOCK_ROOT, address, port, path));
     }
 
     private String newMappingUrl() {
@@ -81,9 +80,6 @@ private String newMappingUrl() {
     private String editMappingUrl() {
         return String.format(LOCAL_WIREMOCK_EDIT_RESPONSE_URL, address, port);
     }
-    private String removeMappingUrl() {
-        return String.format(LOCAL_WIREMOCK_REMOVE_RESPONSE_URL, address, port);
-    }
     private String resetUrl() {
         return String.format(LOCAL_WIREMOCK_RESET_URL, address, port);
     }
@@ -93,7 +89,8 @@ private String resetDefaultMappingsUrl() {
     }
 
     public WireMockResponse get(String url, TestHttpHeader... headers) {
-        String actualUrl = URI.create(url).isAbsolute() ? url : mockServiceUrlFor(url);
+        URI uri = URI.create(url);
+        URI actualUrl = uri.isAbsolute() ? uri : mockServiceUrlFor(url);
         HttpUriRequest httpRequest = new HttpGet(actualUrl);
         return executeMethodAndConvertExceptions(httpRequest, headers);
     }
@@ -104,8 +101,8 @@ public WireMockResponse getViaProxy(String url) {
 
     public WireMockResponse getViaProxy(String url, int proxyPort) {
         URI targetUri = URI.create(url);
-        HttpHost proxy = new HttpHost(address, proxyPort, targetUri.getScheme());
-        HttpClient httpClientUsingProxy = HttpClientBuilder.create()
+        HttpHost proxy = new HttpHost(targetUri.getScheme(), address, proxyPort);
+        CloseableHttpClient httpClientUsingProxy = HttpClientBuilder.create()
             .disableAuthCaching()
             .disableAutomaticRetries()
             .disableCookieManagement()
@@ -114,13 +111,13 @@ public WireMockResponse getViaProxy(String url, int proxyPort) {
             .build();
 
         try {
-            HttpHost target = new HttpHost(targetUri.getHost(), targetUri.getPort(), targetUri.getScheme());
+            HttpHost target = new HttpHost(targetUri.getScheme(), targetUri.getHost(), targetUri.getPort());
             HttpGet req = new HttpGet(targetUri.getPath() +
                 (isNullOrEmpty(targetUri.getQuery()) ? "" : "?" + targetUri.getQuery()));
             req.removeHeaders("Host");
 
             System.out.println("executing request to " + targetUri + "(" + target + ") via " + proxy);
-            HttpResponse httpResponse = httpClientUsingProxy.execute(target, req);
+            ClassicHttpResponse httpResponse = httpClientUsingProxy.execute(target, req);
             return new WireMockResponse(httpResponse);
         } catch (IOException ioe) {
             throw new RuntimeException(ioe);
@@ -143,7 +140,7 @@ public WireMockResponse patchWithBody(String url, String body, String contentTyp
     }
 
     private WireMockResponse requestWithBody(
-        HttpEntityEnclosingRequestBase request, String body, String contentType, TestHttpHeader... headers) {
+            HttpUriRequestBase request, String body, String contentType, TestHttpHeader... headers) {
         request.setEntity(new StringEntity(body, ContentType.create(contentType, "utf-8")));
         return executeMethodAndConvertExceptions(request, headers);
     }
@@ -153,7 +150,7 @@ public WireMockResponse postWithBody(String url, String body, String bodyMimeTyp
     }
 
     public WireMockResponse postWithChunkedBody(String url, byte[] body) {
-        return post(url, new InputStreamEntity(new ByteArrayInputStream(body), -1));
+        return post(url, new InputStreamEntity(new ByteArrayInputStream(body), -1, ContentType.DEFAULT_BINARY));
     }
 
     public WireMockResponse post(String url, HttpEntity entity, TestHttpHeader... headers) {
@@ -222,8 +219,8 @@ private int postJsonAndReturnStatus(String url, String json) {
             if (json != null) {
                 post.setEntity(new StringEntity(json, ContentType.create(JSON.toString(), "utf-8")));
             }
-            HttpResponse httpResponse = httpClient().execute(post);
-            return httpResponse.getStatusLine().getStatusCode();
+            ClassicHttpResponse httpResponse = httpClient().execute(post);
+            return httpResponse.getCode();
         } catch (RuntimeException re) {
             throw re;
         } catch (Exception e) {
@@ -240,7 +237,7 @@ private WireMockResponse executeMethodAndConvertExceptions(HttpUriRequest httpRe
             for (TestHttpHeader header : headers) {
                 httpRequest.addHeader(header.getName(), header.getValue());
             }
-            HttpResponse httpResponse = httpClient().execute(httpRequest);
+            ClassicHttpResponse httpResponse = httpClient().execute(httpRequest);
             return new WireMockResponse(httpResponse);
         } catch (IOException ioe) {
             throw new RuntimeException(ioe);
@@ -249,7 +246,7 @@ private WireMockResponse executeMethodAndConvertExceptions(HttpUriRequest httpRe
 
     public WireMockResponse getWithPreemptiveCredentials(String url, int port, String username, String password) {
         HttpHost target = new HttpHost("localhost", port);
-        HttpClient httpClient = httpClientWithPreemptiveAuth(target, username, password);
+        CloseableHttpClient httpClient = httpClientWithPreemptiveAuth(target, username, password);
 
         AuthCache authCache = new BasicAuthCache();
         BasicScheme basicAuth = new BasicScheme();
@@ -259,7 +256,7 @@ public WireMockResponse getWithPreemptiveCredentials(String url, int port, Strin
 
         try {
             HttpGet httpget = new HttpGet(url);
-            HttpResponse response = httpClient.execute(target, httpget, localContext);
+            ClassicHttpResponse response = httpClient.execute(target, httpget, localContext);
             return new WireMockResponse(response);
         } catch (IOException e) {
             return throwUnchecked(e, WireMockResponse.class);
@@ -267,11 +264,11 @@ public WireMockResponse getWithPreemptiveCredentials(String url, int port, Strin
     }
 
     public WireMockResponse request(final String methodName, String url, TestHttpHeader... headers) {
-        HttpUriRequest httpRequest = new GenericHttpUriRequest(methodName, mockServiceUrlFor(url));
+        HttpUriRequest httpRequest = new HttpUriRequestBase(methodName, mockServiceUrlFor(url));
         return executeMethodAndConvertExceptions(httpRequest, headers);
     }
 
-    private static HttpClient httpClient() {
+    private static CloseableHttpClient httpClient() {
         return HttpClientBuilder.create()
             .disableAuthCaching()
             .disableAutomaticRetries()
@@ -281,11 +278,11 @@ private static HttpClient httpClient() {
             .build();
     }
 
-    private static HttpClient httpClientWithPreemptiveAuth(HttpHost target, String username, String password) {
-        CredentialsProvider credsProvider = new BasicCredentialsProvider();
+    private static CloseableHttpClient httpClientWithPreemptiveAuth(HttpHost target, String username, String password) {
+    	BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
         credsProvider.setCredentials(
             new AuthScope(target),
-            new UsernamePasswordCredentials(username, password));
+            new UsernamePasswordCredentials(username, password.toCharArray()));
 
         return HttpClients.custom()
             .setDefaultCredentialsProvider(credsProvider)