From 3af9838a6d20ef5bda236b6f4195ed54b896e44b Mon Sep 17 00:00:00 2001 From: Adam Retter Date: Tue, 18 Jun 2024 10:33:15 +0200 Subject: [PATCH] Update to Apache Http Components 5 --- http-client-java/pom.xml | 8 +- .../org/expath/httpclient/ContentType.java | 13 +- .../java/org/expath/httpclient/HeaderSet.java | 6 +- .../httpclient/impl/AnyEmptyMethod.java | 23 +- .../httpclient/impl/AnyEntityMethod.java | 23 +- .../httpclient/impl/ApacheHttpConnection.java | 229 +++++++++++------- .../expath/httpclient/impl/BodyFactory.java | 17 +- .../httpclient/impl/HttpRequestImpl.java | 14 +- .../expath/httpclient/impl/LoggerHelper.java | 11 +- .../httpclient/impl/MultipartRequestBody.java | 4 +- .../impl/MultipartResponseBody.java | 2 +- http-client-parent/pom.xml | 12 +- http-client-saxon/pom.xml | 4 +- .../httpclient/saxon/SaxonTreeBuilder.java | 2 +- 14 files changed, 205 insertions(+), 163 deletions(-) diff --git a/http-client-java/pom.xml b/http-client-java/pom.xml index 798a14c..e82caf4 100644 --- a/http-client-java/pom.xml +++ b/http-client-java/pom.xml @@ -60,12 +60,12 @@ tools-java - org.apache.httpcomponents - httpcore + org.apache.httpcomponents.core5 + httpcore5 - org.apache.httpcomponents - httpclient + org.apache.httpcomponents.client5 + httpclient5 org.ccil.cowan.tagsoup diff --git a/http-client-java/src/main/java/org/expath/httpclient/ContentType.java b/http-client-java/src/main/java/org/expath/httpclient/ContentType.java index ebc8495..dafb53c 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/ContentType.java +++ b/http-client-java/src/main/java/org/expath/httpclient/ContentType.java @@ -9,9 +9,10 @@ package org.expath.httpclient; -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.NameValuePair; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HeaderElement; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.message.MessageSupport; import javax.annotation.Nullable; @@ -50,7 +51,7 @@ public ContentType(final String type, final String charset, final String boundar if (header == null || !"Content-Type".equalsIgnoreCase(header.getName())) { throw new HttpClientException(HttpClientError.HC001, "Header is not content type"); } - final HeaderElement[] headerElements = header.getElements(); + final HeaderElement[] headerElements = MessageSupport.parse(header); if (headerElements.length > 1) { throw new HttpClientException(HttpClientError.HC001, "Multiple Content-Type headers"); } @@ -71,7 +72,7 @@ public ContentType(final String type, final String charset, final String boundar if (header == null || !"Content-Type".equalsIgnoreCase(header.getName())) { throw new HttpClientException(HttpClientError.HC001, "Header is not content type"); } - final HeaderElement[] headerElements = header.getElements(); + final HeaderElement[] headerElements = MessageSupport.parse(header); if (headerElements.length > 1) { throw new HttpClientException(HttpClientError.HC001, "Multiple Content-Type headers"); } @@ -90,7 +91,7 @@ public ContentType(final String type, final String charset, final String boundar throw new HttpClientException(HttpClientError.HC001, "Header is not Content-Type"); } - final HeaderElement[] headerElements = header.getElements(); + final HeaderElement[] headerElements = MessageSupport.parse(header); if (headerElements.length > 1) { throw new HttpClientException(HttpClientError.HC001, "Multiple Content-Type headers"); } diff --git a/http-client-java/src/main/java/org/expath/httpclient/HeaderSet.java b/http-client-java/src/main/java/org/expath/httpclient/HeaderSet.java index 22255fa..255fbb9 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/HeaderSet.java +++ b/http-client-java/src/main/java/org/expath/httpclient/HeaderSet.java @@ -14,9 +14,9 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.message.BasicHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HeaderElement; +import org.apache.hc.core5.http.message.BasicHeader; /** * TODO: Doc... diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEmptyMethod.java b/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEmptyMethod.java index 0bc71e7..c84b4de 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEmptyMethod.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEmptyMethod.java @@ -10,7 +10,7 @@ package org.expath.httpclient.impl; import java.net.URI; -import org.apache.http.client.methods.HttpRequestBase; +import org.apache.hc.core5.http.message.BasicClassicHttpRequest; /** * Implements any HTTP extension method, without any entity content. @@ -23,35 +23,22 @@ * @author Florent Georges */ public class AnyEmptyMethod - extends HttpRequestBase + extends BasicClassicHttpRequest { public AnyEmptyMethod(String method) { - super(); - METHOD_NAME = method; + super(method, (String) null); } public AnyEmptyMethod(String method, URI uri) { - super(); - METHOD_NAME = method; - setURI(uri); + super(method, uri); } public AnyEmptyMethod(String method, String uri) { - super(); - METHOD_NAME = method; - setURI(URI.create(uri)); + super(method, URI.create(uri)); } - - @Override - public String getMethod() - { - return METHOD_NAME; - } - - public String METHOD_NAME; } diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEntityMethod.java b/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEntityMethod.java index 7c04b04..24e6881 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEntityMethod.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/AnyEntityMethod.java @@ -10,7 +10,7 @@ package org.expath.httpclient.impl; import java.net.URI; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.hc.core5.http.message.BasicClassicHttpRequest; /** * Implements any HTTP extension method, without any entity content. @@ -23,35 +23,22 @@ * @author Florent Georges */ public class AnyEntityMethod - extends HttpEntityEnclosingRequestBase + extends BasicClassicHttpRequest { public AnyEntityMethod(String method) { - super(); - METHOD_NAME = method; + super(method, (String) null); } public AnyEntityMethod(String method, URI uri) { - super(); - METHOD_NAME = method; - setURI(uri); + super(method, uri); } public AnyEntityMethod(String method, String uri) { - super(); - METHOD_NAME = method; - setURI(URI.create(uri)); + super(method, URI.create(uri)); } - - @Override - public String getMethod() - { - return METHOD_NAME; - } - - public String METHOD_NAME; } diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/ApacheHttpConnection.java b/http-client-java/src/main/java/org/expath/httpclient/impl/ApacheHttpConnection.java index 08e2cc9..2a2d1ae 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/ApacheHttpConnection.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/ApacheHttpConnection.java @@ -15,42 +15,69 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.net.URI; +import java.net.URISyntaxException; import java.util.concurrent.TimeUnit; import java.util.zip.GZIPOutputStream; import net.jcip.annotations.NotThreadSafe; -import org.expath.httpclient.*; +import org.apache.hc.core5.http.ClassicHttpRequest; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpHeaders; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.HttpVersion; +import org.apache.hc.core5.http.config.Registry; +import org.apache.hc.core5.http.config.RegistryBuilder; +import org.apache.hc.core5.http.io.entity.AbstractHttpEntity; +import org.apache.hc.core5.http.io.entity.ByteArrayEntity; +import org.apache.hc.core5.http.message.StatusLine; +import org.apache.hc.core5.http.protocol.HttpContext; +import org.apache.hc.core5.io.IOCallback; +import org.apache.hc.core5.ssl.SSLContexts; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.TimeValue; +import org.apache.hc.client5.http.auth.AuthScheme; +import org.apache.hc.client5.http.auth.AuthScope; +import org.apache.hc.client5.http.auth.Credentials; +import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; +import org.apache.hc.client5.http.auth.AuthCache; +import org.apache.hc.client5.http.cookie.BasicCookieStore; +import org.apache.hc.client5.http.cookie.CookieStore; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.cookie.StandardCookieSpec; +import org.apache.hc.client5.http.entity.GzipCompressingEntity; +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpHead; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpOptions; +import org.apache.hc.client5.http.classic.methods.HttpPatch; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpTrace; +import org.apache.hc.client5.http.impl.DefaultRedirectStrategy; +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.auth.DigestScheme; +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.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.routing.SystemDefaultRoutePlanner; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.client5.http.socket.ConnectionSocketFactory; +import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.expath.httpclient.HeaderSet; +import org.expath.httpclient.HttpClientError; +import org.expath.httpclient.HttpClientException; +import org.expath.httpclient.HttpConnection; +import org.expath.httpclient.HttpConstants; +import org.expath.httpclient.HttpCredentials; +import org.expath.httpclient.HttpRequestBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.HttpVersion; -import org.apache.http.auth.AuthScheme; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.Credentials; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.AuthCache; -import org.apache.http.client.CookieStore; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.entity.GzipCompressingEntity; -import org.apache.http.client.methods.*; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.entity.ContentProducer; -import org.apache.http.entity.EntityTemplate; -import org.apache.http.impl.auth.BasicScheme; -import org.apache.http.impl.auth.DigestScheme; -import org.apache.http.impl.client.*; -import org.apache.http.impl.conn.*; -import org.apache.http.protocol.HTTP; -import org.apache.http.protocol.HttpContext; -import org.apache.http.ssl.SSLContexts; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; @@ -80,7 +107,7 @@ public void connect(final HttpRequestBody body, final HttpCredentials cred) throw new HttpClientException(HttpClientError.HC001, "setRequestMethod has not been called before"); } - myRequest.setProtocolVersion(myVersion); + myRequest.setVersion(myVersion); try { // make a new client @@ -100,12 +127,12 @@ public void connect(final HttpRequestBody body, final HttpCredentials cred) // log the request headers? if ( LOG.isDebugEnabled() ) { LOG.debug("METHOD: " + myRequest.getMethod()); - Header[] headers = myRequest.getAllHeaders(); + Header[] headers = myRequest.getHeaders(); LoggerHelper.logHeaders(LOG, "REQ HEADERS", headers); LoggerHelper.logCookies(LOG, "COOKIES", COOKIES.getCookies()); } // send the request - myResponse = myClient.execute(myRequest, clientContext); + myResponse = myClient.execute(myRequest, clientContext); //TODO(AR) use execute method that takes additional HttpClientResponseHandler instead // TODO: Handle 'Connection' headers (for instance "Connection: close") // See for instance http://www.jmarshall.com/easy/http/. @@ -113,7 +140,7 @@ public void connect(final HttpRequestBody body, final HttpCredentials cred) // log the response headers? if ( LOG.isDebugEnabled() ) { - Header[] headers = myResponse.getAllHeaders(); + Header[] headers = myResponse.getHeaders(); LoggerHelper.logHeaders(LOG, "RESP HEADERS", headers); LoggerHelper.logCookies(LOG, "COOKIES", COOKIES.getCookies()); } @@ -213,6 +240,9 @@ else if ( "HEAD".equals(m) ) { else if ( "OPTIONS".equals(m) ) { myRequest = new HttpOptions(uri); } + else if ( "PATCH".equals(m) ) { + myRequest = new HttpPatch(uri); + } else if ( "POST".equals(m) ) { myRequest = new HttpPost(uri); } @@ -315,18 +345,18 @@ else if ( excl.indexOf(c) == -1 ) { public int getResponseStatus() { - return myResponse.getStatusLine().getStatusCode(); + return new StatusLine(myResponse).getStatusCode(); } public String getResponseMessage() { - return myResponse.getStatusLine().getReasonPhrase(); + return new StatusLine(myResponse).getReasonPhrase(); } public HeaderSet getResponseHeaders() throws HttpClientException { - return new HeaderSet(myResponse.getAllHeaders()); + return new HeaderSet(myResponse.getHeaders()); } /** @@ -359,7 +389,8 @@ private CloseableHttpClient makeClient() { // do follow redirections? if(myFollowRedirect) { - clientBuilder.setRedirectStrategy(LaxRedirectStrategy.INSTANCE); + //clientBuilder.setRedirectStrategy(LaxRedirectStrategy.INSTANCE); + clientBuilder.setRedirectStrategy(DefaultRedirectStrategy.INSTANCE); } else { clientBuilder.disableRedirectHandling(); } @@ -369,11 +400,12 @@ private CloseableHttpClient makeClient() { // set the timeout if any final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + requestConfigBuilder.setCookieSpec(StandardCookieSpec.STRICT); if(myTimeout != null) { // See http://blog.jayway.com/2009/03/17/configuring-timeout-with-apache-httpclient-40/ requestConfigBuilder - .setConnectTimeout(myTimeout * 1000) - .setSocketTimeout(myTimeout * 1000); + .setConnectTimeout(myTimeout, TimeUnit.SECONDS); + //.setSocketTimeout(myTimeout, TimeUnit.SECONDS); } clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build()); @@ -392,7 +424,12 @@ private HttpClientContext setCredentials(HttpCredentials cred) return clientContext; } - final URI uri = myRequest.getURI(); + final URI uri; + try { + uri = myRequest.getUri(); + } catch (final URISyntaxException e) { + throw new HttpClientException(HttpClientError.HC005, "Unable to parse request uri: " + e.getMessage(), e); + } final String scheme = uri.getScheme(); int port = uri.getPort(); if (port == -1) { @@ -406,7 +443,7 @@ private HttpClientContext setCredentials(HttpCredentials cred) } final String host = uri.getHost(); - final HttpHost targetHost = new HttpHost(host, port, scheme); + final HttpHost targetHost = new HttpHost(scheme, host, port); final String user = cred.getUser(); final String pwd = cred.getPwd(); @@ -416,17 +453,16 @@ private HttpClientContext setCredentials(HttpCredentials cred) + " - " + user + " - ***"); } - final Credentials c = new UsernamePasswordCredentials(user, pwd); - final AuthScope scope = new AuthScope(targetHost); - if (clientContext.getCredentialsProvider() == null) { - clientContext.setCredentialsProvider(new BasicCredentialsProvider()); + final Credentials c = new UsernamePasswordCredentials(user, pwd.toCharArray()); + final AuthScope scope = new AuthScope(targetHost); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(scope, c); + clientContext.setCredentialsProvider(credentialsProvider); } else { - clientContext.getCredentialsProvider().clear(); + clientContext.setCredentialsProvider(null); } - clientContext.getCredentialsProvider().setCredentials(scope, c); - // force preemptive authentication? // see - https://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html#d5e717 if (myPreemptiveAuthentication) { @@ -469,10 +505,16 @@ private void setRequestEntity(HttpRequestBody body) if(myChunked) { // Take advantage of HTTP 1.1 chunked encoding to stream the // payload directly to the request. - final ContentProducer producer = new RequestBodyProducer(body); - final EntityTemplate entityTemplate = new EntityTemplate(producer); - entityTemplate.setContentType(body.getContentType()); - entityTemplate.setChunked(true); + + // TODO(AR) do we need to set contentEncoding in this constructor if `myGzip` is set? + final AbstractHttpEntity entityTemplate = new ChunkedEntityTemplate(ContentType.parse(body.getContentType()), null, out -> { + try { + body.serialize(out); + } catch (final HttpClientException ex) { + throw new IOException("Error serializing the body content", ex); + } + }); + template = entityTemplate; } else { @@ -483,7 +525,7 @@ private void setRequestEntity(HttpRequestBody body) */ try (final ByteArrayOutputStream buffer = new ByteArrayOutputStream()) { body.serialize(buffer); - template = new ByteArrayEntity(buffer.toByteArray()); + template = new ByteArrayEntity(buffer.toByteArray(), ContentType.parse(body.getContentType())); } catch (final IOException e) { throw new HttpClientException(HttpClientError.HC001, e.getMessage(), e); } @@ -504,27 +546,18 @@ private void setRequestEntity(HttpRequestBody body) try (final GZIPOutputStream gzip = new GZIPOutputStream(buffer)) { body.serialize(gzip); } - myRequest.setHeader(HTTP.CONTENT_ENCODING, "gzip"); + myRequest.setHeader(HttpHeaders.CONTENT_ENCODING, "gzip"); } else { body.serialize(buffer); } - entity = new ByteArrayEntity(buffer.toByteArray()); + entity = new ByteArrayEntity(buffer.toByteArray(), ContentType.parse(body.getContentType())); } catch (final IOException e) { throw new HttpClientException(HttpClientError.HC001, e.getMessage(), e); } } - // cast the request - HttpEntityEnclosingRequestBase req = null; - if ( ! (myRequest instanceof HttpEntityEnclosingRequestBase) ) { - String msg = "Body not allowed on a " + myRequest.getMethod() + " request"; - throw new HttpClientException(HttpClientError.HC001, msg); - } - else { - req = (HttpEntityEnclosingRequestBase) myRequest; - } // set the entity on the request - req.setEntity(entity); + myRequest.setEntity(entity); } private static PoolingHttpClientConnectionManager setupConnectionPool() { @@ -538,8 +571,8 @@ private static PoolingHttpClientConnectionManager setupConnectionPool() { .register("http", PlainConnectionSocketFactory.INSTANCE) .build(); - final PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null, 15, TimeUnit.MINUTES); //TODO(AR) TTL is currently 15 minutes, make configurable? - poolingHttpClientConnectionManager.setMaxTotal(40); //TODO(AR) total pooled connections is 40, make configurable? + final PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, TimeValue.of(15, TimeUnit.MINUTES)); //TODO(AR) TTL is currently 15 minutes, make configurable? + poolingHttpClientConnectionManager.setMaxTotal(40); //TODO(AR) total pooled connections is 40, make configurable? poolingHttpClientConnectionManager.setDefaultMaxPerRoute(2); //TODO(AR) max default connections per route is 2, make configurable? return poolingHttpClientConnectionManager; } @@ -550,11 +583,11 @@ private static PoolingHttpClientConnectionManager setupConnectionPool() { */ private static class SSLSocketFactoryWithSNI extends SSLConnectionSocketFactory { public SSLSocketFactoryWithSNI(final SSLContext sslContext) { - super(sslContext); + super(sslContext, new String[] { "TLSv1.2", "TLSv1.3"}, null, null); } @Override - public Socket connectSocket(final int connectTimeout, final Socket socket, final HttpHost host, + public Socket connectSocket(final TimeValue connectTimeout, final Socket socket, final HttpHost host, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpContext context) throws IOException { if (socket instanceof SSLSocket) { @@ -586,7 +619,7 @@ private enum State { /** The Apache client. */ private CloseableHttpClient myClient; /** The Apache request. */ - private HttpRequestBase myRequest; + private ClassicHttpRequest myRequest; /** The Apache response. */ private CloseableHttpResponse myResponse; /** The HTTP protocol version. */ @@ -634,29 +667,45 @@ else if ( "1.1".equals(ver) ) { } } - /** - * A request entity producer, generating content from an {@link HttpRequestBody}. - */ - private static class RequestBodyProducer - implements ContentProducer - { - public RequestBodyProducer(HttpRequestBody body) - { - myBody = body; + private static class ChunkedEntityTemplate extends AbstractHttpEntity { + private final IOCallback callback; + + public ChunkedEntityTemplate(final ContentType contentType, final String contentEncoding, final IOCallback callback) { + super(contentType, contentEncoding, true); + this.callback = Args.notNull(callback, "I/O callback"); } - public void writeTo(OutputStream out) - throws IOException - { - try { - myBody.serialize(out); - } - catch ( HttpClientException ex ) { - throw new IOException("Error serializing the body content", ex); - } + @Override + public long getContentLength() { + return -1; // not known! + } + + @Override + public InputStream getContent() throws IOException { + final ByteArrayOutputStream buf = new ByteArrayOutputStream(); + writeTo(buf); + return new ByteArrayInputStream(buf.toByteArray()); + } + + @Override + public boolean isRepeatable() { + return true; } - private HttpRequestBody myBody; + @Override + public void writeTo(final OutputStream outStream) throws IOException { + Args.notNull(outStream, "Output stream"); + this.callback.execute(outStream); + } + + @Override + public boolean isStreaming() { + return false; + } + + @Override + public void close() throws IOException { + } } } diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/BodyFactory.java b/http-client-java/src/main/java/org/expath/httpclient/impl/BodyFactory.java index 6f9b552..1f797bb 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/BodyFactory.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/BodyFactory.java @@ -13,10 +13,17 @@ import java.util.HashSet; import java.util.Set; -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.message.BasicHeader; -import org.expath.httpclient.*; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HeaderElement; +import org.apache.hc.core5.http.message.BasicHeader; +import org.apache.hc.core5.http.message.MessageSupport; +import org.expath.httpclient.ContentType; +import org.expath.httpclient.HeaderSet; +import org.expath.httpclient.HttpClientError; +import org.expath.httpclient.HttpClientException; +import org.expath.httpclient.HttpConnection; +import org.expath.httpclient.HttpRequestBody; +import org.expath.httpclient.HttpResponseBody; import org.expath.httpclient.model.Result; import org.expath.tools.model.Element; import org.expath.tools.model.Sequence; @@ -205,7 +212,7 @@ private static Type parseType(final Element elem) throws HttpClientException { throw new HttpClientException(HttpClientError.HC001, "@media-type is not set on http:body"); } final Header mediaTypeHeader = new BasicHeader("Media-Type", mediaType); - final HeaderElement[] mediaTypeHeaderElems = mediaTypeHeader.getElements(); + final HeaderElement[] mediaTypeHeaderElems = MessageSupport.parse(mediaTypeHeader); if (mediaTypeHeaderElems == null || mediaTypeHeaderElems.length == 0) { throw new HttpClientException(HttpClientError.HC001, "@media-type is not set on http:body"); } else if (mediaTypeHeaderElems.length > 1) { diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/HttpRequestImpl.java b/http-client-java/src/main/java/org/expath/httpclient/impl/HttpRequestImpl.java index a4c67e2..55453da 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/HttpRequestImpl.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/HttpRequestImpl.java @@ -9,10 +9,20 @@ package org.expath.httpclient.impl; -import org.expath.httpclient.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.http.Header; +import org.apache.hc.core5.http.Header; +import org.expath.httpclient.ContentType; +import org.expath.httpclient.HeaderSet; +import org.expath.httpclient.HttpClientError; +import org.expath.httpclient.HttpClientException; +import org.expath.httpclient.HttpRequestBody; +import org.expath.httpclient.HttpConnection; +import org.expath.httpclient.HttpConstants; +import org.expath.httpclient.HttpCredentials; +import org.expath.httpclient.HttpRequest; +import org.expath.httpclient.HttpResponse; +import org.expath.httpclient.HttpResponseBody; import org.expath.httpclient.model.Result; import javax.annotation.Nullable; diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/LoggerHelper.java b/http-client-java/src/main/java/org/expath/httpclient/impl/LoggerHelper.java index 92eb180..5d0c116 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/LoggerHelper.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/LoggerHelper.java @@ -10,10 +10,11 @@ package org.expath.httpclient.impl; import org.slf4j.Logger; -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.NameValuePair; -import org.apache.http.cookie.Cookie; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HeaderElement; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.message.MessageSupport; +import org.apache.hc.client5.http.cookie.Cookie; /** * Helper to log HTTP-specific stuff. @@ -57,7 +58,7 @@ public static void logHeaderDetails(Logger log, String prompt, Iterable
} for ( Header h : headers ) { log.debug(prompt + " - HEADER: " + h.getName() + ": " + h.getValue()); - for ( HeaderElement e : h.getElements() ) { + for ( HeaderElement e : MessageSupport.parse(h) ) { log.debug(prompt + " - ELEM: " + e.getName() + ": " + e.getValue()); for ( NameValuePair p : e.getParameters() ) { log.debug(prompt + " - P: " + p.getName() + ": " + p.getValue()); diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartRequestBody.java b/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartRequestBody.java index 4a04782..dc6e803 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartRequestBody.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartRequestBody.java @@ -13,8 +13,8 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; -import org.apache.http.Header; -import org.apache.http.message.BasicHeader; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.message.BasicHeader; import org.expath.httpclient.ContentType; import org.expath.httpclient.HeaderSet; import org.expath.httpclient.HttpClientError; diff --git a/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartResponseBody.java b/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartResponseBody.java index bd90a37..ce3c246 100644 --- a/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartResponseBody.java +++ b/http-client-java/src/main/java/org/expath/httpclient/impl/MultipartResponseBody.java @@ -19,7 +19,7 @@ import org.expath.httpclient.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.http.Header; +import org.apache.hc.core5.http.Header; import org.apache.james.mime4j.MimeException; import org.apache.james.mime4j.stream.EntityState; import org.apache.james.mime4j.stream.Field; diff --git a/http-client-parent/pom.xml b/http-client-parent/pom.xml index 215dd8d..8e7a4ec 100644 --- a/http-client-parent/pom.xml +++ b/http-client-parent/pom.xml @@ -43,14 +43,14 @@ 0.8.0 - org.apache.httpcomponents - httpcore - 4.4.14 + org.apache.httpcomponents.core5 + httpcore5 + 5.2.4 - org.apache.httpcomponents - httpclient - 4.5.13 + org.apache.httpcomponents.client5 + httpclient5 + 5.3.1 diff --git a/http-client-saxon/pom.xml b/http-client-saxon/pom.xml index c359c3f..b6f384a 100644 --- a/http-client-saxon/pom.xml +++ b/http-client-saxon/pom.xml @@ -47,8 +47,8 @@ Saxon-HE - org.apache.httpcomponents - httpcore + org.apache.httpcomponents.core5 + httpcore5 diff --git a/http-client-saxon/src/main/java/org/expath/httpclient/saxon/SaxonTreeBuilder.java b/http-client-saxon/src/main/java/org/expath/httpclient/saxon/SaxonTreeBuilder.java index b013385..31ed519 100644 --- a/http-client-saxon/src/main/java/org/expath/httpclient/saxon/SaxonTreeBuilder.java +++ b/http-client-saxon/src/main/java/org/expath/httpclient/saxon/SaxonTreeBuilder.java @@ -10,7 +10,7 @@ package org.expath.httpclient.saxon; import net.sf.saxon.expr.XPathContext; -import org.apache.http.Header; +import org.apache.hc.core5.http.Header; import org.expath.httpclient.HeaderSet; import org.expath.httpclient.HttpClientError; import org.expath.httpclient.HttpClientException;