From 5f800413a371dcb07e794e8d03cafad8b2d65110 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Wed, 11 Jan 2017 23:44:17 +0000 Subject: [PATCH 01/10] Refactor magic number. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1778357 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/main/java/org/apache/http/util/EntityUtils.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/httpcore/src/main/java/org/apache/http/util/EntityUtils.java b/httpcore/src/main/java/org/apache/http/util/EntityUtils.java index 83297f09a4..e401f4eecf 100644 --- a/httpcore/src/main/java/org/apache/http/util/EntityUtils.java +++ b/httpcore/src/main/java/org/apache/http/util/EntityUtils.java @@ -50,6 +50,8 @@ */ public final class EntityUtils { + private static final int DEFAULT_BUFFER_SIZE = 4096; + private EntityUtils() { } @@ -128,10 +130,10 @@ public static byte[] toByteArray(final HttpEntity entity) throws IOException { "HTTP entity too large to be buffered in memory"); int i = (int)entity.getContentLength(); if (i < 0) { - i = 4096; + i = DEFAULT_BUFFER_SIZE; } final ByteArrayBuffer buffer = new ByteArrayBuffer(i); - final byte[] tmp = new byte[4096]; + final byte[] tmp = new byte[DEFAULT_BUFFER_SIZE]; int l; while((l = instream.read(tmp)) != -1) { buffer.append(tmp, 0, l); @@ -205,7 +207,7 @@ private static String toString( "HTTP entity too large to be buffered in memory"); int i = (int)entity.getContentLength(); if (i < 0) { - i = 4096; + i = DEFAULT_BUFFER_SIZE; } Charset charset = null; if (contentType != null) { From f484626c086537409e8091ba9bd521e503ae4119 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Wed, 11 Jan 2017 23:45:05 +0000 Subject: [PATCH 02/10] Better local var name. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1778358 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/http/util/EntityUtils.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/httpcore/src/main/java/org/apache/http/util/EntityUtils.java b/httpcore/src/main/java/org/apache/http/util/EntityUtils.java index e401f4eecf..ac795b2dd1 100644 --- a/httpcore/src/main/java/org/apache/http/util/EntityUtils.java +++ b/httpcore/src/main/java/org/apache/http/util/EntityUtils.java @@ -128,11 +128,11 @@ public static byte[] toByteArray(final HttpEntity entity) throws IOException { try { Args.check(entity.getContentLength() <= Integer.MAX_VALUE, "HTTP entity too large to be buffered in memory"); - int i = (int)entity.getContentLength(); - if (i < 0) { - i = DEFAULT_BUFFER_SIZE; + int capacity = (int)entity.getContentLength(); + if (capacity < 0) { + capacity = DEFAULT_BUFFER_SIZE; } - final ByteArrayBuffer buffer = new ByteArrayBuffer(i); + final ByteArrayBuffer buffer = new ByteArrayBuffer(capacity); final byte[] tmp = new byte[DEFAULT_BUFFER_SIZE]; int l; while((l = instream.read(tmp)) != -1) { @@ -205,9 +205,9 @@ private static String toString( try { Args.check(entity.getContentLength() <= Integer.MAX_VALUE, "HTTP entity too large to be buffered in memory"); - int i = (int)entity.getContentLength(); - if (i < 0) { - i = DEFAULT_BUFFER_SIZE; + int capacity = (int)entity.getContentLength(); + if (capacity < 0) { + capacity = DEFAULT_BUFFER_SIZE; } Charset charset = null; if (contentType != null) { @@ -221,7 +221,7 @@ private static String toString( charset = HTTP.DEF_CONTENT_CHARSET; } final Reader reader = new InputStreamReader(instream, charset); - final CharArrayBuffer buffer = new CharArrayBuffer(i); + final CharArrayBuffer buffer = new CharArrayBuffer(capacity); final char[] tmp = new char[1024]; int l; while((l = reader.read(tmp)) != -1) { From 10331fe5e854cbf8067aa12b7cd441192751a188 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Mon, 23 Jan 2017 19:59:46 +0000 Subject: [PATCH 03/10] HTTPCORE-442: Non-blocking SSL sessions fail to decrypt buffered input data in some cases if closed by the opposite endpoint git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1779966 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/http/nio/reactor/ssl/SSLIOSession.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java index f619155674..a84d1ffb0a 100644 --- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java +++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java @@ -470,19 +470,20 @@ private boolean decryptData() throws SSLException { try { if (!inEncryptedBuf.hasRemaining() && result.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) { - throw new SSLException("Input buffer is full"); + throw new SSLException("Unable to complete SSL handshake"); } - if (result.getStatus() == Status.OK) { + final Status status = result.getStatus(); + if (status == Status.OK) { decrypted = true; } else { + if (status == Status.BUFFER_UNDERFLOW && this.endOfStream) { + throw new SSLException("Unable to decrypt incoming data due to unexpected end of stream"); + } break; } if (result.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) { break; } - if (this.endOfStream) { - break; - } } finally { // Release inEncrypted if empty if (this.inEncrypted.acquire().position() == 0) { From e555fabb7a2f0458cbe1cce3d5d6983f200bd018 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Sat, 28 Jan 2017 09:50:13 +0000 Subject: [PATCH 04/10] HTTPCLIENT-1808: Fixing potential overflow for connection TTL Contributed by Andrew Shore git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1780648 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/main/java/org/apache/http/pool/PoolEntry.java | 8 +++++--- .../src/test/java/org/apache/http/pool/TestPoolEntry.java | 6 ++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java b/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java index 31b8ee2819..dad51399d0 100644 --- a/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java +++ b/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java @@ -26,12 +26,12 @@ */ package org.apache.http.pool; -import java.util.concurrent.TimeUnit; - import org.apache.http.annotation.Contract; import org.apache.http.annotation.ThreadingBehavior; import org.apache.http.util.Args; +import java.util.concurrent.TimeUnit; + /** * Pool entry containing a pool connection object along with its route. *

@@ -85,7 +85,9 @@ public PoolEntry(final String id, final T route, final C conn, this.created = System.currentTimeMillis(); this.updated = this.created; if (timeToLive > 0) { - this.validityDeadline = this.created + tunit.toMillis(timeToLive); + final long deadline = this.created + tunit.toMillis(timeToLive); + // If the above overflows then default to Long.MAX_VALUE + this.validityDeadline = deadline > 0 ? deadline : Long.MAX_VALUE; } else { this.validityDeadline = Long.MAX_VALUE; } diff --git a/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java b/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java index 927f160bc7..6bad38e744 100644 --- a/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java +++ b/httpcore/src/test/java/org/apache/http/pool/TestPoolEntry.java @@ -122,4 +122,10 @@ public void testInvalidExpiry() throws Exception { entry1.updateExpiry(50L, null); } + @Test + public void testExpiryDoesNotOverflow() { + final MockPoolEntry entry = new MockPoolEntry("route1", Long.MAX_VALUE, TimeUnit.MILLISECONDS); + Assert.assertEquals(entry.getValidityDeadline(), Long.MAX_VALUE); + } + } From 217e68e0c486cd51817fad6fb97eb55640256451 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Sat, 28 Jan 2017 10:34:41 +0000 Subject: [PATCH 05/10] HTTPASYNC-116: Remove cancelled lease requests from the request queue when validating pending requests git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1780653 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/http/nio/pool/AbstractNIOConnPool.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java b/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java index b4ee96d022..603b71debe 100644 --- a/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java +++ b/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java @@ -484,11 +484,18 @@ public void validatePendingRequests() { final ListIterator> it = this.leasingRequests.listIterator(); while (it.hasNext()) { final LeaseRequest request = it.next(); - final long deadline = request.getDeadline(); - if (now > deadline) { + final BasicFuture future = request.getFuture(); + if (future.isCancelled() && !request.isDone()) { it.remove(); - request.failed(new TimeoutException()); - this.completedRequests.add(request); + } else { + final long deadline = request.getDeadline(); + if (now > deadline) { + request.failed(new TimeoutException()); + } + if (request.isDone()) { + it.remove(); + this.completedRequests.add(request); + } } } } finally { From f7b81af572dbd129850825ce240d0685f8664d04 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Tue, 21 Feb 2017 20:00:33 +0000 Subject: [PATCH 06/10] HTTPCORE-446: fixed deadlock in AbstractConnPool shutdown code git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1783929 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/http/pool/AbstractConnPool.java | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java index d34cf24192..25a6bfc4fc 100644 --- a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java +++ b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java @@ -38,6 +38,8 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -190,37 +192,37 @@ public Future lease(final T route, final Object state, final FutureCallback() { - private volatile boolean cancelled; - private volatile boolean done; - private volatile E entry; + private final AtomicBoolean cancelled = new AtomicBoolean(false); + private final AtomicBoolean done = new AtomicBoolean(false); + private final AtomicReference entryRef = new AtomicReference(null); @Override public boolean cancel(final boolean mayInterruptIfRunning) { - cancelled = true; - lock.lock(); - try { - condition.signalAll(); - } finally { - lock.unlock(); - } - synchronized (this) { - final boolean result = !done; - done = true; + if (cancelled.compareAndSet(false, true)) { + done.set(true); + lock.lock(); + try { + condition.signalAll(); + } finally { + lock.unlock(); + } if (callback != null) { callback.cancelled(); } - return result; + return true; + } else { + return false; } } @Override public boolean isCancelled() { - return cancelled; + return cancelled.get(); } @Override public boolean isDone() { - return done; + return done.get(); } @Override @@ -234,6 +236,7 @@ public E get() throws InterruptedException, ExecutionException { @Override public E get(final long timeout, final TimeUnit tunit) throws InterruptedException, ExecutionException, TimeoutException { + final E entry = entryRef.get(); if (entry != null) { return entry; } @@ -250,16 +253,16 @@ public E get(final long timeout, final TimeUnit tunit) throws InterruptedExcepti } } } - entry = leasedEntry; - done = true; - onLease(entry); + entryRef.set(leasedEntry); + done.set(true); + onLease(leasedEntry); if (callback != null) { - callback.completed(entry); + callback.completed(leasedEntry); } - return entry; + return leasedEntry; } } catch (IOException ex) { - done = true; + done.set(true); if (callback != null) { callback.failed(ex); } From 2e2d511b869b01479fc26a21f8a97aab4f828e11 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Thu, 23 Feb 2017 13:22:39 +0000 Subject: [PATCH 07/10] HTTPCORE-447: HttpHost#create does not throw IllegalArgumentException for empty string git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1784126 13f79535-47bb-0310-9956-ffa450edef68 --- httpcore/src/main/java/org/apache/http/util/Args.java | 3 +++ httpcore/src/test/java/org/apache/http/TestHttpHost.java | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/httpcore/src/main/java/org/apache/http/util/Args.java b/httpcore/src/main/java/org/apache/http/util/Args.java index 9eb8a251ff..6f08674b8e 100644 --- a/httpcore/src/main/java/org/apache/http/util/Args.java +++ b/httpcore/src/main/java/org/apache/http/util/Args.java @@ -80,6 +80,9 @@ public static T containsNoBlanks(final T argument, fina if (argument == null) { throw new IllegalArgumentException(name + " may not be null"); } + if (argument.length() == 0) { + throw new IllegalArgumentException(name + " may not be empty"); + } if (TextUtils.containsBlanks(argument)) { throw new IllegalArgumentException(name + " may not contain blanks"); } diff --git a/httpcore/src/test/java/org/apache/http/TestHttpHost.java b/httpcore/src/test/java/org/apache/http/TestHttpHost.java index 71f161b122..674d9e3bb5 100644 --- a/httpcore/src/test/java/org/apache/http/TestHttpHost.java +++ b/httpcore/src/test/java/org/apache/http/TestHttpHost.java @@ -222,6 +222,11 @@ public void testCreateFromStringInvalid() throws Exception { Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException expected) { } + try { + HttpHost.create(""); + Assert.fail("IllegalArgumentException expected"); + } catch (final IllegalArgumentException expected) { + } } } From b7cbb7943e0f4398864198b9dc9fe37b0dc151c9 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sun, 26 Mar 2017 02:26:35 +0000 Subject: [PATCH 08/10] Use final. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1788706 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/http/nio/pool/AbstractNIOConnPool.java | 2 +- .../org/apache/http/nio/reactor/ssl/SSLIOSession.java | 2 +- .../apache/http/impl/nio/codecs/TestChunkDecoder.java | 8 ++++---- .../http/impl/nio/reactor/TestSessionInOutBuffers.java | 4 ++-- .../integration/TestClientOutOfSequenceResponse.java | 2 +- .../integration/TestHttpAsyncHandlersPipelining.java | 10 +++++----- .../org/apache/http/nio/testserver/HttpClientNio.java | 2 +- .../main/java/org/apache/http/entity/ContentType.java | 2 +- .../java/org/apache/http/pool/AbstractConnPool.java | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java b/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java index 603b71debe..77824b4ef0 100644 --- a/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java +++ b/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java @@ -691,7 +691,7 @@ public PoolStats getStats(final T route) { try { final RouteSpecificPool pool = getPool(route); int pendingCount = 0; - for (LeaseRequest request: leasingRequests) { + for (final LeaseRequest request: leasingRequests) { if (LangUtils.equals(route, request.getRoute())) { pendingCount++; } diff --git a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java index a84d1ffb0a..e47cf117e2 100644 --- a/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java +++ b/httpcore-nio/src/main/java/org/apache/http/nio/reactor/ssl/SSLIOSession.java @@ -637,7 +637,7 @@ public synchronized void close() { this.sslEngine.closeOutbound(); try { updateEventMask(); - } catch (CancelledKeyException ex) { + } catch (final CancelledKeyException ex) { shutdown(); } } diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java index 97bf84e7fb..40ecabe2a7 100644 --- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java +++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/codecs/TestChunkDecoder.java @@ -433,7 +433,7 @@ public void testTooLongChunkHeader() throws Exception { try { decoder2.read(dst); Assert.fail("MessageConstraintException expected"); - } catch (MessageConstraintException ex) { + } catch (final MessageConstraintException ex) { } } @@ -470,7 +470,7 @@ public void testTooLongFooter() throws Exception { try { decoder2.read(dst); Assert.fail("MessageConstraintException expected"); - } catch (MessageConstraintException ex) { + } catch (final MessageConstraintException ex) { } } @@ -506,7 +506,7 @@ public void testTooLongFoldedFooter() throws Exception { try { decoder2.read(dst); Assert.fail("MessageConstraintException expected"); - } catch (MessageConstraintException ex) { + } catch (final MessageConstraintException ex) { } } @@ -543,7 +543,7 @@ public void testTooManyFooters() throws Exception { try { decoder2.read(dst); Assert.fail("MessageConstraintException expected"); - } catch (MessageConstraintException ex) { + } catch (final MessageConstraintException ex) { } } diff --git a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java index b9df858a26..89f6c5462d 100644 --- a/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java +++ b/httpcore-nio/src/test/java/org/apache/http/impl/nio/reactor/TestSessionInOutBuffers.java @@ -153,7 +153,7 @@ public void testLineLimit() throws Exception { try { inbuf2.readLine(line, false); Assert.fail("MessageConstraintException expected"); - } catch (MessageConstraintException ex) { + } catch (final MessageConstraintException ex) { } } @@ -176,7 +176,7 @@ public void testLineLimitBufferFull() throws Exception { try { inbuf2.readLine(line, false); Assert.fail("MessageConstraintException expected"); - } catch (MessageConstraintException ex) { + } catch (final MessageConstraintException ex) { } } diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestClientOutOfSequenceResponse.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestClientOutOfSequenceResponse.java index 52edb5304e..ff87f20010 100644 --- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestClientOutOfSequenceResponse.java +++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestClientOutOfSequenceResponse.java @@ -99,7 +99,7 @@ public void testOutOfSequenceResponse() throws Exception { try { final HttpResponse response2 = future2.get(); Assert.assertEquals(200, response2.getStatusLine().getStatusCode()); - } catch (ExecutionException ex) { + } catch (final ExecutionException ex) { Assert.assertTrue(ex.getCause() instanceof HttpException); } } diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java index 9a02593601..a4c258634a 100644 --- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java +++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestHttpAsyncHandlersPipelining.java @@ -169,7 +169,7 @@ public void testHttpGets() throws Exception { final List responses = future.get(); Assert.assertNotNull(responses); Assert.assertEquals(3, responses.size()); - for (HttpResponse response: responses) { + for (final HttpResponse response: responses) { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity())); } @@ -203,7 +203,7 @@ public void testHttpHeads() throws Exception { final List responses = future.get(); Assert.assertNotNull(responses); Assert.assertEquals(3, responses.size()); - for (HttpResponse response: responses) { + for (final HttpResponse response: responses) { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); } } @@ -247,7 +247,7 @@ public void testHttpPosts() throws Exception { final List responses = future.get(); Assert.assertNotNull(responses); Assert.assertEquals(3, responses.size()); - for (HttpResponse response: responses) { + for (final HttpResponse response: responses) { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals(expectedPattern, EntityUtils.toString(response.getEntity())); } @@ -335,7 +335,7 @@ public void run() { final List responses = future.get(); Assert.assertNotNull(responses); Assert.assertEquals(3, responses.size()); - for (HttpResponse response: responses) { + for (final HttpResponse response: responses) { Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); } Assert.assertEquals(expectedPattern1, EntityUtils.toString(responses.get(0).getEntity())); @@ -397,7 +397,7 @@ public void handle( final Future> future = this.client.executePipelined(target, requestProducers, responseConsumers, null, null); try { future.get(); - } catch (ExecutionException ex) { + } catch (final ExecutionException ex) { final Throwable cause = ex.getCause(); Assert.assertTrue(cause instanceof ConnectionClosedException); } diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java index 8a2f13dd85..3e46a57794 100644 --- a/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java +++ b/httpcore-nio/src/test/java/org/apache/http/nio/testserver/HttpClientNio.java @@ -179,7 +179,7 @@ public Future> executePipelined( new ArrayList(requests.size()); final List> responseConsumers = new ArrayList>(requests.size()); - for (HttpRequest request: requests) { + for (final HttpRequest request: requests) { requestProducers.add(new BasicAsyncRequestProducer(target, request)); responseConsumers.add(new BasicAsyncResponseConsumer()); } diff --git a/httpcore/src/main/java/org/apache/http/entity/ContentType.java b/httpcore/src/main/java/org/apache/http/entity/ContentType.java index 122d17fcfd..4491e56019 100644 --- a/httpcore/src/main/java/org/apache/http/entity/ContentType.java +++ b/httpcore/src/main/java/org/apache/http/entity/ContentType.java @@ -110,7 +110,7 @@ public final class ContentType implements Serializable { TEXT_PLAIN, TEXT_XML }; final HashMap map = new HashMap(); - for (ContentType contentType: contentTypes) { + for (final ContentType contentType: contentTypes) { map.put(contentType.getMimeType(), contentType); } CONTENT_TYPE_MAP = Collections.unmodifiableMap(map); diff --git a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java index 25a6bfc4fc..6e09832657 100644 --- a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java +++ b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java @@ -229,7 +229,7 @@ public boolean isDone() { public E get() throws InterruptedException, ExecutionException { try { return get(0L, TimeUnit.MILLISECONDS); - } catch (TimeoutException ex) { + } catch (final TimeoutException ex) { throw new ExecutionException(ex); } } @@ -261,7 +261,7 @@ public E get(final long timeout, final TimeUnit tunit) throws InterruptedExcepti } return leasedEntry; } - } catch (IOException ex) { + } catch (final IOException ex) { done.set(true); if (callback != null) { callback.failed(ex); From 0962ff44074b80795ef32f8f56ce92c77116681d Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Sun, 26 Mar 2017 02:28:02 +0000 Subject: [PATCH 09/10] Add missing '@Override' annotations. git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpcore/branches/4.4.x@1788707 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/impl/AbstractHttpClientConnection.java | 8 ++++++++ .../http/impl/AbstractHttpServerConnection.java | 7 +++++++ .../http/impl/SocketHttpClientConnection.java | 9 +++++++++ .../http/impl/SocketHttpServerConnection.java | 9 +++++++++ .../http/impl/io/AbstractSessionInputBuffer.java | 9 +++++++++ .../http/impl/io/AbstractSessionOutputBuffer.java | 10 ++++++++++ .../apache/http/impl/io/SocketInputBuffer.java | 2 ++ .../apache/http/params/DefaultedHttpParams.java | 4 ++++ .../apache/http/protocol/BasicHttpProcessor.java | 15 +++++++++++++++ .../http/protocol/DefaultedHttpContext.java | 3 +++ .../http/protocol/HttpRequestHandlerRegistry.java | 1 + .../org/apache/http/util/CharArrayBuffer.java | 2 ++ 12 files changed, 79 insertions(+) diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java index 672e482804..fecec648a2 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpClientConnection.java @@ -236,6 +236,7 @@ protected void init( outbuffer.getMetrics()); } + @Override public boolean isResponseAvailable(final int timeout) throws IOException { assertOpen(); try { @@ -245,6 +246,7 @@ public boolean isResponseAvailable(final int timeout) throws IOException { } } + @Override public void sendRequestHeader(final HttpRequest request) throws HttpException, IOException { Args.notNull(request, "HTTP request"); @@ -253,6 +255,7 @@ public void sendRequestHeader(final HttpRequest request) this.metrics.incrementRequestCount(); } + @Override public void sendRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException { Args.notNull(request, "HTTP request"); @@ -270,11 +273,13 @@ protected void doFlush() throws IOException { this.outbuffer.flush(); } + @Override public void flush() throws IOException { assertOpen(); doFlush(); } + @Override public HttpResponse receiveResponseHeader() throws HttpException, IOException { assertOpen(); @@ -285,6 +290,7 @@ public HttpResponse receiveResponseHeader() return response; } + @Override public void receiveResponseEntity(final HttpResponse response) throws HttpException, IOException { Args.notNull(response, "HTTP response"); @@ -297,6 +303,7 @@ protected boolean isEof() { return this.eofSensor != null && this.eofSensor.isEof(); } + @Override public boolean isStale() { if (!isOpen()) { return true; @@ -314,6 +321,7 @@ public boolean isStale() { } } + @Override public HttpConnectionMetrics getMetrics() { return this.metrics; } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java index 8abc573fc1..28465a4cd1 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/AbstractHttpServerConnection.java @@ -236,6 +236,7 @@ protected void init( outbuffer.getMetrics()); } + @Override public HttpRequest receiveRequestHeader() throws HttpException, IOException { assertOpen(); @@ -244,6 +245,7 @@ public HttpRequest receiveRequestHeader() return request; } + @Override public void receiveRequestEntity(final HttpEntityEnclosingRequest request) throws HttpException, IOException { Args.notNull(request, "HTTP request"); @@ -256,11 +258,13 @@ protected void doFlush() throws IOException { this.outbuffer.flush(); } + @Override public void flush() throws IOException { assertOpen(); doFlush(); } + @Override public void sendResponseHeader(final HttpResponse response) throws HttpException, IOException { Args.notNull(response, "HTTP response"); @@ -271,6 +275,7 @@ public void sendResponseHeader(final HttpResponse response) } } + @Override public void sendResponseEntity(final HttpResponse response) throws HttpException, IOException { if (response.getEntity() == null) { @@ -286,6 +291,7 @@ protected boolean isEof() { return this.eofSensor != null && this.eofSensor.isEof(); } + @Override public boolean isStale() { if (!isOpen()) { return true; @@ -301,6 +307,7 @@ public boolean isStale() { } } + @Override public HttpConnectionMetrics getMetrics() { return this.metrics; } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java index 0980ab53ad..0d98a8860d 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpClientConnection.java @@ -151,6 +151,7 @@ protected void bind( this.open = true; } + @Override public boolean isOpen() { return this.open; } @@ -159,6 +160,7 @@ protected Socket getSocket() { return this.socket; } + @Override public InetAddress getLocalAddress() { if (this.socket != null) { return this.socket.getLocalAddress(); @@ -167,6 +169,7 @@ public InetAddress getLocalAddress() { } } + @Override public int getLocalPort() { if (this.socket != null) { return this.socket.getLocalPort(); @@ -175,6 +178,7 @@ public int getLocalPort() { } } + @Override public InetAddress getRemoteAddress() { if (this.socket != null) { return this.socket.getInetAddress(); @@ -183,6 +187,7 @@ public InetAddress getRemoteAddress() { } } + @Override public int getRemotePort() { if (this.socket != null) { return this.socket.getPort(); @@ -191,6 +196,7 @@ public int getRemotePort() { } } + @Override public void setSocketTimeout(final int timeout) { assertOpen(); if (this.socket != null) { @@ -204,6 +210,7 @@ public void setSocketTimeout(final int timeout) { } } + @Override public int getSocketTimeout() { if (this.socket != null) { try { @@ -216,6 +223,7 @@ public int getSocketTimeout() { } } + @Override public void shutdown() throws IOException { this.open = false; final Socket tmpsocket = this.socket; @@ -224,6 +232,7 @@ public void shutdown() throws IOException { } } + @Override public void close() throws IOException { if (!this.open) { return; diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java index dfffe8be9c..c34305826f 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/SocketHttpServerConnection.java @@ -144,10 +144,12 @@ protected Socket getSocket() { return this.socket; } + @Override public boolean isOpen() { return this.open; } + @Override public InetAddress getLocalAddress() { if (this.socket != null) { return this.socket.getLocalAddress(); @@ -156,6 +158,7 @@ public InetAddress getLocalAddress() { } } + @Override public int getLocalPort() { if (this.socket != null) { return this.socket.getLocalPort(); @@ -164,6 +167,7 @@ public int getLocalPort() { } } + @Override public InetAddress getRemoteAddress() { if (this.socket != null) { return this.socket.getInetAddress(); @@ -172,6 +176,7 @@ public InetAddress getRemoteAddress() { } } + @Override public int getRemotePort() { if (this.socket != null) { return this.socket.getPort(); @@ -180,6 +185,7 @@ public int getRemotePort() { } } + @Override public void setSocketTimeout(final int timeout) { assertOpen(); if (this.socket != null) { @@ -193,6 +199,7 @@ public void setSocketTimeout(final int timeout) { } } + @Override public int getSocketTimeout() { if (this.socket != null) { try { @@ -205,6 +212,7 @@ public int getSocketTimeout() { } } + @Override public void shutdown() throws IOException { this.open = false; final Socket tmpsocket = this.socket; @@ -213,6 +221,7 @@ public void shutdown() throws IOException { } } + @Override public void close() throws IOException { if (!this.open) { return; diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java index d36d8e4c3c..7a3367164b 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionInputBuffer.java @@ -124,6 +124,7 @@ protected HttpTransportMetricsImpl createTransportMetrics() { /** * @since 4.1 */ + @Override public int capacity() { return this.buffer.length; } @@ -131,6 +132,7 @@ public int capacity() { /** * @since 4.1 */ + @Override public int length() { return this.bufferlen - this.bufferpos; } @@ -138,6 +140,7 @@ public int length() { /** * @since 4.1 */ + @Override public int available() { return capacity() - length(); } @@ -169,6 +172,7 @@ protected boolean hasBufferedData() { return this.bufferpos < this.bufferlen; } + @Override public int read() throws IOException { int noRead; while (!hasBufferedData()) { @@ -180,6 +184,7 @@ public int read() throws IOException { return this.buffer[this.bufferpos++] & 0xff; } + @Override public int read(final byte[] b, final int off, final int len) throws IOException { if (b == null) { return 0; @@ -213,6 +218,7 @@ public int read(final byte[] b, final int off, final int len) throws IOException } } + @Override public int read(final byte[] b) throws IOException { if (b == null) { return 0; @@ -244,6 +250,7 @@ private int locateLF() { * @return one line of characters * @exception IOException if an I/O error occurs. */ + @Override public int readLine(final CharArrayBuffer charbuffer) throws IOException { Args.notNull(charbuffer, "Char array buffer"); int noRead = 0; @@ -382,6 +389,7 @@ private int handleDecodingResult( return len; } + @Override public String readLine() throws IOException { final CharArrayBuffer charbuffer = new CharArrayBuffer(64); final int l = readLine(charbuffer); @@ -392,6 +400,7 @@ public String readLine() throws IOException { } } + @Override public HttpTransportMetrics getMetrics() { return this.metrics; } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java index 02662329e9..aba72eadad 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/AbstractSessionOutputBuffer.java @@ -133,6 +133,7 @@ protected HttpTransportMetricsImpl createTransportMetrics() { /** * @since 4.1 */ + @Override public int capacity() { return this.buffer.capacity(); } @@ -140,6 +141,7 @@ public int capacity() { /** * @since 4.1 */ + @Override public int length() { return this.buffer.length(); } @@ -147,6 +149,7 @@ public int length() { /** * @since 4.1 */ + @Override public int available() { return capacity() - length(); } @@ -160,11 +163,13 @@ protected void flushBuffer() throws IOException { } } + @Override public void flush() throws IOException { flushBuffer(); this.outstream.flush(); } + @Override public void write(final byte[] b, final int off, final int len) throws IOException { if (b == null) { return; @@ -190,6 +195,7 @@ public void write(final byte[] b, final int off, final int len) throws IOExcepti } } + @Override public void write(final byte[] b) throws IOException { if (b == null) { return; @@ -197,6 +203,7 @@ public void write(final byte[] b) throws IOException { write(b, 0, b.length); } + @Override public void write(final int b) throws IOException { if (this.buffer.isFull()) { flushBuffer(); @@ -213,6 +220,7 @@ public void write(final int b) throws IOException { * @param s the line. * @exception IOException if an I/O error occurs. */ + @Override public void writeLine(final String s) throws IOException { if (s == null) { return; @@ -239,6 +247,7 @@ public void writeLine(final String s) throws IOException { * @param charbuffer the buffer containing chars of the line. * @exception IOException if an I/O error occurs. */ + @Override public void writeLine(final CharArrayBuffer charbuffer) throws IOException { if (charbuffer == null) { return; @@ -298,6 +307,7 @@ private void handleEncodingResult(final CoderResult result) throws IOException { this.bbuf.compact(); } + @Override public HttpTransportMetrics getMetrics() { return this.metrics; } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java index 86f39dc289..246ca0ad77 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/impl/io/SocketInputBuffer.java @@ -84,6 +84,7 @@ protected int fillBuffer() throws IOException { return i; } + @Override public boolean isDataAvailable(final int timeout) throws IOException { boolean result = hasBufferedData(); if (!result) { @@ -99,6 +100,7 @@ public boolean isDataAvailable(final int timeout) throws IOException { return result; } + @Override public boolean isEof() { return this.eof; } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java b/httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java index 5731c410a0..547e5cb8ec 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/params/DefaultedHttpParams.java @@ -64,6 +64,7 @@ public DefaultedHttpParams(final HttpParams local, final HttpParams defaults) { /** * Creates a copy of the local collection with the same default */ + @Override public HttpParams copy() { final HttpParams clone = this.local.copy(); return new DefaultedHttpParams(clone, this.defaults); @@ -74,6 +75,7 @@ public HttpParams copy() { * parameter is not set locally, delegates its resolution to the default * collection. */ + @Override public Object getParameter(final String name) { Object obj = this.local.getParameter(name); if (obj == null && this.defaults != null) { @@ -86,6 +88,7 @@ public Object getParameter(final String name) { * Attempts to remove the parameter from the local collection. This method * does not modify the default collection. */ + @Override public boolean removeParameter(final String name) { return this.local.removeParameter(name); } @@ -94,6 +97,7 @@ public boolean removeParameter(final String name) { * Sets the parameter in the local collection. This method does not * modify the default collection. */ + @Override public HttpParams setParameter(final String name, final Object value) { return this.local.setParameter(name, value); } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java index 33f4f5d5e4..681140cbfb 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/BasicHttpProcessor.java @@ -57,6 +57,7 @@ public final class BasicHttpProcessor implements protected final List requestInterceptors = new ArrayList(); protected final List responseInterceptors = new ArrayList(); + @Override public void addRequestInterceptor(final HttpRequestInterceptor itcp) { if (itcp == null) { return; @@ -64,6 +65,7 @@ public void addRequestInterceptor(final HttpRequestInterceptor itcp) { this.requestInterceptors.add(itcp); } + @Override public void addRequestInterceptor( final HttpRequestInterceptor itcp, final int index) { if (itcp == null) { @@ -72,6 +74,7 @@ public void addRequestInterceptor( this.requestInterceptors.add(index, itcp); } + @Override public void addResponseInterceptor( final HttpResponseInterceptor itcp, final int index) { if (itcp == null) { @@ -80,6 +83,7 @@ public void addResponseInterceptor( this.responseInterceptors.add(index, itcp); } + @Override public void removeRequestInterceptorByClass(final Class clazz) { for (final Iterator it = this.requestInterceptors.iterator(); it.hasNext(); ) { @@ -90,6 +94,7 @@ public void removeRequestInterceptorByClass(final Class clazz) { for (final Iterator it = this.responseInterceptors.iterator(); it.hasNext(); ) { @@ -108,10 +113,12 @@ public final void addInterceptor(final HttpRequestInterceptor interceptor, final addRequestInterceptor(interceptor, index); } + @Override public int getRequestInterceptorCount() { return this.requestInterceptors.size(); } + @Override public HttpRequestInterceptor getRequestInterceptor(final int index) { if ((index < 0) || (index >= this.requestInterceptors.size())) { return null; @@ -119,10 +126,12 @@ public HttpRequestInterceptor getRequestInterceptor(final int index) { return this.requestInterceptors.get(index); } + @Override public void clearRequestInterceptors() { this.requestInterceptors.clear(); } + @Override public void addResponseInterceptor(final HttpResponseInterceptor itcp) { if (itcp == null) { return; @@ -138,10 +147,12 @@ public final void addInterceptor(final HttpResponseInterceptor interceptor, fina addResponseInterceptor(interceptor, index); } + @Override public int getResponseInterceptorCount() { return this.responseInterceptors.size(); } + @Override public HttpResponseInterceptor getResponseInterceptor(final int index) { if ((index < 0) || (index >= this.responseInterceptors.size())) { return null; @@ -149,6 +160,7 @@ public HttpResponseInterceptor getResponseInterceptor(final int index) { return this.responseInterceptors.get(index); } + @Override public void clearResponseInterceptors() { this.responseInterceptors.clear(); } @@ -170,6 +182,7 @@ public void clearResponseInterceptors() { * @param list the list of request and response interceptors * from which to initialize */ + @Override public void setInterceptors(final List list) { Args.notNull(list, "Inteceptor list"); this.requestInterceptors.clear(); @@ -192,6 +205,7 @@ public void clearInterceptors() { clearResponseInterceptors(); } + @Override public void process( final HttpRequest request, final HttpContext context) @@ -201,6 +215,7 @@ public void process( } } + @Override public void process( final HttpResponse response, final HttpContext context) diff --git a/httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java index abcf7f03e3..12172719ed 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/DefaultedHttpContext.java @@ -51,6 +51,7 @@ public DefaultedHttpContext(final HttpContext local, final HttpContext defaults) this.defaults = defaults; } + @Override public Object getAttribute(final String id) { final Object obj = this.local.getAttribute(id); if (obj == null) { @@ -60,10 +61,12 @@ public Object getAttribute(final String id) { } } + @Override public Object removeAttribute(final String id) { return this.local.removeAttribute(id); } + @Override public void setAttribute(final String id, final Object obj) { this.local.setAttribute(id, obj); } diff --git a/httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java b/httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java index 33b9932276..a86633a974 100644 --- a/httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java +++ b/httpcore/src/main/java-deprecated/org/apache/http/protocol/HttpRequestHandlerRegistry.java @@ -101,6 +101,7 @@ public Map getHandlers() { return matcher.getObjects(); } + @Override public HttpRequestHandler lookup(final String requestURI) { return matcher.lookup(requestURI); } diff --git a/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java b/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java index 4af2e25639..36c4d750bc 100644 --- a/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java +++ b/httpcore/src/main/java/org/apache/http/util/CharArrayBuffer.java @@ -257,6 +257,7 @@ public char[] toCharArray() { * @throws IndexOutOfBoundsException if {@code index} is * negative or greater than or equal to {@link #length()}. */ + @Override public char charAt(final int i) { return this.buffer[i]; } @@ -286,6 +287,7 @@ public int capacity() { * * @return the length of the buffer */ + @Override public int length() { return this.len; } From 6a85e569f0b6e6c2f90896e6f265d465066a76cc Mon Sep 17 00:00:00 2001 From: lujianbo <387852424@qq.com> Date: Mon, 3 Apr 2017 17:54:49 +0800 Subject: [PATCH 10/10] add a provider parameter in SSLContextBuilder In 4.4.x branch --- .../org/apache/http/ssl/SSLContextBuilder.java | 16 ++++++++++++++-- .../apache/http/ssl/TestSSLContextBuilder.java | 13 +++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java b/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java index 067a0c4c34..2fe30b9257 100644 --- a/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java +++ b/httpcore/src/main/java/org/apache/http/ssl/SSLContextBuilder.java @@ -39,6 +39,7 @@ import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.PrivateKey; +import java.security.Provider; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; @@ -80,6 +81,7 @@ public class SSLContextBuilder { private final Set keymanagers; private final Set trustmanagers; private SecureRandom secureRandom; + private Provider provider; public static SSLContextBuilder create() { return new SSLContextBuilder(); @@ -101,6 +103,11 @@ public SSLContextBuilder setSecureRandom(final SecureRandom secureRandom) { return this; } + public SSLContextBuilder setProvider(final Provider provider) { + this.provider = provider; + return this; + } + public SSLContextBuilder loadTrustMaterial( final KeyStore truststore, final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException { @@ -266,8 +273,13 @@ protected void initSSLContext( } public SSLContext build() throws NoSuchAlgorithmException, KeyManagementException { - final SSLContext sslcontext = SSLContext.getInstance( - this.protocol != null ? this.protocol : TLS); + final SSLContext sslcontext; + final String protocolStr = this.protocol != null ? this.protocol : TLS; + if (this.provider != null) { + sslcontext = SSLContext.getInstance(protocolStr, this.provider); + } else { + sslcontext = SSLContext.getInstance(protocolStr); + } initSSLContext(sslcontext, keymanagers, trustmanagers, secureRandom); return sslcontext; } diff --git a/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java b/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java index 61992be0af..ae132f0aab 100644 --- a/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java +++ b/httpcore/src/test/java/org/apache/http/ssl/TestSSLContextBuilder.java @@ -37,6 +37,7 @@ import java.net.URL; import java.security.KeyStore; import java.security.Principal; +import java.security.Security; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; @@ -618,4 +619,16 @@ public Boolean call() throws Exception { } } + @Test + public void testBuildWithProvider() throws Exception { + final URL resource1 = getClass().getResource("/test-server.keystore"); + final String storePassword = "nopassword"; + final String keyPassword = "nopassword"; + final SSLContext sslContext=SSLContextBuilder.create() + .setProvider(Security.getProvider("SunJSSE")) + .loadKeyMaterial(resource1, storePassword.toCharArray(), keyPassword.toCharArray()) + .build(); + Assert.assertTrue(sslContext.getProvider().getName().equals("SunJSSE")); + } + }