You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/07/25 21:23:16 UTC
[httpcomponents-core] branch fix-backport updated (8837e29 ->
8e0254c)
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a change to branch fix-backport
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git.
discard 8837e29 Bug fix: ensure consistency of internal buffers in case of I/O or SSL exception (back-ported from master)
discard 1891750 TLS integration tests
new 6f18099 Bug fix: ensure consistency of internal buffers in case of I/O or SSL exception (back-ported from master)
new 8e0254c TLS integration tests
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (8837e29)
\
N -- N -- N refs/heads/fix-backport (8e0254c)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../test/java/org/apache/http/nio/integration/TestTLSIntegration.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[httpcomponents-core] 01/02: Bug fix: ensure consistency of
internal buffers in case of I/O or SSL exception (back-ported from master)
Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch fix-backport
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit 6f18099315fe0e841df2abddbe48a737226fdaef
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Jul 25 22:18:51 2019 +0200
Bug fix: ensure consistency of internal buffers in case of I/O or SSL exception (back-ported from master)
---
.../apache/http/nio/reactor/ssl/SSLIOSession.java | 24 +++++++++++++++-------
1 file changed, 17 insertions(+), 7 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 3abca05..5b571d8 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
@@ -317,9 +317,11 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
// Perform operations
inEncryptedBuf.flip();
- result = doUnwrap(inEncryptedBuf, inPlainBuf);
- inEncryptedBuf.compact();
-
+ try {
+ result = doUnwrap(inEncryptedBuf, inPlainBuf);
+ } finally {
+ inEncryptedBuf.compact();
+ }
try {
if (!inEncryptedBuf.hasRemaining() && result.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
@@ -430,10 +432,14 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
// Acquire buffer
final ByteBuffer outEncryptedBuf = this.outEncrypted.acquire();
+ final int bytesWritten;
// Perform operation
outEncryptedBuf.flip();
- final int bytesWritten = this.session.channel().write(outEncryptedBuf);
- outEncryptedBuf.compact();
+ try {
+ bytesWritten = this.session.channel().write(outEncryptedBuf);
+ } finally {
+ outEncryptedBuf.compact();
+ }
// Release if empty
if (outEncryptedBuf.position() == 0) {
@@ -470,10 +476,14 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
final ByteBuffer inEncryptedBuf = this.inEncrypted.acquire();
final ByteBuffer inPlainBuf = this.inPlain.acquire();
+ final SSLEngineResult result;
// Perform operations
inEncryptedBuf.flip();
- final SSLEngineResult result = doUnwrap(inEncryptedBuf, inPlainBuf);
- inEncryptedBuf.compact();
+ try {
+ result = doUnwrap(inEncryptedBuf, inPlainBuf);
+ } finally {
+ inEncryptedBuf.compact();
+ }
try {
if (!inEncryptedBuf.hasRemaining() && result.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
[httpcomponents-core] 02/02: TLS integration tests
Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch fix-backport
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
commit 8e0254c11de8d0071eb2741292a8de8f3b310165
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Jul 25 22:11:27 2019 +0200
TLS integration tests
---
.../apache/http/nio/integration/TestCustomSSL.java | 157 --------
.../http/nio/integration/TestTLSIntegration.java | 404 +++++++++++++++++++++
2 files changed, 404 insertions(+), 157 deletions(-)
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestCustomSSL.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestCustomSSL.java
deleted file mode 100644
index a1caec4..0000000
--- a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestCustomSSL.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.http.nio.integration;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.InetSocketAddress;
-import java.net.URL;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSession;
-
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
-import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.nio.NHttpConnection;
-import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
-import org.apache.http.nio.reactor.IOSession;
-import org.apache.http.nio.reactor.ListenerEndpoint;
-import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
-import org.apache.http.nio.testserver.ClientConnectionFactory;
-import org.apache.http.nio.testserver.HttpClientNio;
-import org.apache.http.nio.testserver.HttpServerNio;
-import org.apache.http.nio.testserver.ServerConnectionFactory;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.HttpCoreContext;
-import org.apache.http.protocol.HttpRequestHandler;
-import org.apache.http.ssl.SSLContextBuilder;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class TestCustomSSL {
-
- private final static long RESULT_TIMEOUT_SEC = 30;
-
- protected HttpServerNio server;
- protected HttpClientNio client;
-
- @After
- public void shutDownClient() throws Exception {
- if (this.client != null) {
- this.client.shutdown();
- this.client = null;
- }
- }
-
- @After
- public void shutDownServer() throws Exception {
- if (this.server != null) {
- this.server.shutdown();
- this.server = null;
- }
- }
-
- @Test
- public void testCustomSSLContext() throws Exception {
- final SSLSetupHandler sslSetupHandler = new SSLSetupHandler() {
-
- @Override
- public void initalize(
- final SSLEngine sslengine) throws SSLException {
- }
-
- @Override
- public void verify(
- final IOSession ioSession, final SSLSession sslsession) throws SSLException {
- final BigInteger sslid = new BigInteger(sslsession.getId());
- ioSession.setAttribute("ssl-id", sslid);
- }
-
- };
-
- final HttpRequestHandler requestHandler = new HttpRequestHandler() {
-
- @Override
- public void handle(
- final HttpRequest request,
- final HttpResponse response,
- final HttpContext context) throws HttpException, IOException {
- final NHttpConnection conn = (NHttpConnection) context.getAttribute(
- HttpCoreContext.HTTP_CONNECTION);
- final BigInteger sslid = (BigInteger) conn.getContext().getAttribute(
- "ssl-id");
- Assert.assertNotNull(sslid);
- }
-
- };
-
- final URL keyStoreURL = getClass().getResource("/test.keystore");
- final String storePassword = "nopassword";
- final SSLContext serverSSLContext = SSLContextBuilder.create()
- .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
- .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
- .build();
- this.server = new HttpServerNio();
- this.server.setConnectionFactory(new ServerConnectionFactory(serverSSLContext, sslSetupHandler));
- this.server.setTimeout(5000);
-
- final SSLContext clientSSLContext = SSLContextBuilder.create()
- .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
- .build();
-
- this.client = new HttpClientNio(new BasicNIOConnFactory(new ClientConnectionFactory(clientSSLContext), null));
- this.client.setTimeout(5000);
-
- this.server.registerHandler("*", new BasicAsyncRequestHandler(requestHandler));
-
- this.server.start();
- this.client.start();
-
- final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
- endpoint.waitFor();
-
- final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
-
- final HttpHost target = new HttpHost("localhost", address.getPort());
- final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
- final Future<HttpResponse> future = this.client.execute(target, request);
- final HttpResponse response = future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
- Assert.assertNotNull(response);
- Assert.assertEquals(200, response.getStatusLine().getStatusCode());
- }
-
-}
diff --git a/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTLSIntegration.java b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTLSIntegration.java
new file mode 100644
index 0000000..9ab08ba
--- /dev/null
+++ b/httpcore-nio/src/test/java/org/apache/http/nio/integration/TestTLSIntegration.java
@@ -0,0 +1,404 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio.integration;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLSession;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.config.ConnectionConfig;
+import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.nio.NHttpConnection;
+import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.ListenerEndpoint;
+import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
+import org.apache.http.nio.testserver.ClientConnectionFactory;
+import org.apache.http.nio.testserver.HttpClientNio;
+import org.apache.http.nio.testserver.HttpServerNio;
+import org.apache.http.nio.testserver.ServerConnectionFactory;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpCoreContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.ssl.SSLContexts;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+
+public class TestTLSIntegration {
+
+ private final static long RESULT_TIMEOUT_SEC = 30;
+
+ private HttpServerNio server;
+
+ @Rule
+ public ExternalResource serverResource = new ExternalResource() {
+
+ @Override
+ protected void after() {
+ if (server != null) {
+ try {
+ server.shutdown();
+ } catch (final Exception ignore) {
+ }
+ }
+ }
+
+ };
+
+ private HttpClientNio client;
+
+ @Rule
+ public ExternalResource clientResource = new ExternalResource() {
+
+ @Override
+ protected void after() {
+ if (client != null) {
+ try {
+ client.shutdown();
+ } catch (final Exception ignore) {
+ }
+ }
+ }
+
+ };
+
+ private static SSLContext createServerSSLContext() throws Exception {
+ final URL keyStoreURL = TestTLSIntegration.class.getResource("/test.keystore");
+ final String storePassword = "nopassword";
+ return SSLContextBuilder.create()
+ .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
+ .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
+ .build();
+
+ }
+
+ private static SSLContext createClientSSLContext() throws Exception {
+ final URL keyStoreURL = TestTLSIntegration.class.getResource("/test.keystore");
+ final String storePassword = "nopassword";
+ return SSLContextBuilder.create()
+ .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
+ .build();
+ }
+
+ @Test
+ public void testTLSSuccess() throws Exception {
+ server = new HttpServerNio();
+ server.setConnectionFactory(new ServerConnectionFactory(createServerSSLContext(), null));
+ server.setTimeout(5000);
+ server.registerHandler("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
+ server.start();
+
+ final AtomicReference<SSLSession> sslSessionRef = new AtomicReference<SSLSession>(null);
+
+ this.client = new HttpClientNio(new BasicNIOConnFactory(createClientSSLContext(), new SSLSetupHandler() {
+
+ @Override
+ public void initalize(final SSLEngine sslEngine) throws SSLException {
+
+ }
+
+ @Override
+ public void verify(final IOSession ioSession, final SSLSession sslSession) throws SSLException {
+ sslSessionRef.set(sslSession);
+ }
+
+ }, ConnectionConfig.DEFAULT));
+ client.setTimeout(5000);
+ client.start();
+
+ final ListenerEndpoint endpoint = server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+ final HttpHost target = new HttpHost("localhost", address.getPort(), "https");
+
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "BLAHx200");
+ final Future<HttpResponse> future = client.execute(target, request);
+ final HttpResponse response = future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ Assert.assertThat(response, CoreMatchers.notNullValue());
+ Assert.assertThat(response.getStatusLine().getStatusCode(), CoreMatchers.equalTo(200));
+
+ final SSLSession sslSession = sslSessionRef.getAndSet(null);
+ Assert.assertThat(sslSession.getPeerPrincipal().getName(),
+ CoreMatchers.equalTo("CN=localhost,OU=Apache HttpComponents,O=Apache Software Foundation"));
+ }
+
+ @Test
+ public void testTLSTrustFailure() throws Exception {
+ server = new HttpServerNio();
+ server.setConnectionFactory(new ServerConnectionFactory(createServerSSLContext(), null));
+ server.setTimeout(5000);
+ server.registerHandler("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
+ server.start();
+
+ this.client = new HttpClientNio(new BasicNIOConnFactory(SSLContexts.createDefault(), null, ConnectionConfig.DEFAULT));
+ client.setTimeout(5000);
+ client.start();
+
+ final ListenerEndpoint endpoint = server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+ final HttpHost target = new HttpHost("localhost", address.getPort(), "https");
+
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "BLAHx200");
+ final Future<HttpResponse> future = client.execute(target, request);
+ try {
+ future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ Assert.fail("ExecutionException expected");
+ } catch (final ExecutionException ex) {
+ final Throwable cause = ex.getCause();
+ Assert.assertThat(cause, CoreMatchers.<Throwable>instanceOf(SSLHandshakeException.class));
+ }
+ }
+
+ @Test
+ public void testTLSClientAuthFailure() throws Exception {
+ server = new HttpServerNio();
+ server.setConnectionFactory(new ServerConnectionFactory(createServerSSLContext(), new SSLSetupHandler() {
+
+ @Override
+ public void initalize(final SSLEngine sslEngine) throws SSLException {
+ sslEngine.setNeedClientAuth(true);
+ }
+
+ @Override
+ public void verify(final IOSession ioSession, final SSLSession sslSession) throws SSLException {
+ }
+
+ }));
+ server.setTimeout(5000);
+ server.registerHandler("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
+ server.start();
+
+ this.client = new HttpClientNio(new BasicNIOConnFactory(createClientSSLContext(), null, ConnectionConfig.DEFAULT));
+ client.setTimeout(5000);
+ client.start();
+
+ final ListenerEndpoint endpoint = server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+ final HttpHost target = new HttpHost("localhost", address.getPort(), "https");
+
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "BLAHx200");
+ final Future<HttpResponse> future = client.execute(target, request);
+ try {
+ future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ Assert.fail("ExecutionException expected");
+ } catch (final ExecutionException ex) {
+ final Throwable cause = ex.getCause();
+ Assert.assertThat(cause, CoreMatchers.<Throwable>instanceOf(IOException.class));
+ }
+ }
+
+ @Test
+ public void testTLSProtocolMismatch() throws Exception {
+ server = new HttpServerNio();
+ server.setConnectionFactory(new ServerConnectionFactory(createServerSSLContext(), new SSLSetupHandler() {
+
+ @Override
+ public void initalize(final SSLEngine sslEngine) throws SSLException {
+ sslEngine.setEnabledProtocols(new String[]{"TLSv1.2"});
+ }
+
+ @Override
+ public void verify(final IOSession ioSession, final SSLSession sslSession) throws SSLException {
+ }
+
+ }));
+ server.setTimeout(5000);
+ server.registerHandler("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
+ server.start();
+
+ this.client = new HttpClientNio(new BasicNIOConnFactory(createClientSSLContext(), new SSLSetupHandler() {
+
+ @Override
+ public void initalize(final SSLEngine sslEngine) throws SSLException {
+ sslEngine.setEnabledProtocols(new String[]{"SSLv3"});
+ }
+
+ @Override
+ public void verify(final IOSession ioSession, final SSLSession sslSession) throws SSLException {
+ }
+
+ }, ConnectionConfig.DEFAULT));
+ client.setTimeout(5000);
+ client.start();
+
+ final ListenerEndpoint endpoint = server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+ final HttpHost target = new HttpHost("localhost", address.getPort(), "https");
+
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "BLAHx200");
+ final Future<HttpResponse> future = client.execute(target, request);
+ try {
+ future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ Assert.fail("ExecutionException expected");
+ } catch (final ExecutionException ex) {
+ final Throwable cause = ex.getCause();
+ Assert.assertThat(cause, CoreMatchers.<Throwable>instanceOf(IOException.class));
+ }
+ }
+
+ @Test
+ public void testTLSCipherMismatch() throws Exception {
+ server = new HttpServerNio();
+ server.setConnectionFactory(new ServerConnectionFactory(createServerSSLContext(), new SSLSetupHandler() {
+
+ @Override
+ public void initalize(final SSLEngine sslEngine) throws SSLException {
+ sslEngine.setEnabledCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"});
+ }
+
+ @Override
+ public void verify(final IOSession ioSession, final SSLSession sslSession) throws SSLException {
+ }
+
+ }));
+ server.setTimeout(5000);
+ server.registerHandler("*", new BasicAsyncRequestHandler(new SimpleRequestHandler()));
+ server.start();
+
+ this.client = new HttpClientNio(new BasicNIOConnFactory(createClientSSLContext(), new SSLSetupHandler() {
+
+ @Override
+ public void initalize(final SSLEngine sslEngine) throws SSLException {
+ sslEngine.setEnabledCipherSuites(new String[]{"SSL_RSA_EXPORT_WITH_RC4_40_MD5"});
+ }
+
+ @Override
+ public void verify(final IOSession ioSession, final SSLSession sslSession) throws SSLException {
+ }
+
+ }, ConnectionConfig.DEFAULT));
+ client.setTimeout(5000);
+ client.start();
+
+ final ListenerEndpoint endpoint = server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+ final HttpHost target = new HttpHost("localhost", address.getPort(), "https");
+
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "BLAHx200");
+ final Future<HttpResponse> future = client.execute(target, request);
+ try {
+ future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ Assert.fail("ExecutionException expected");
+ } catch (final ExecutionException ex) {
+ final Throwable cause = ex.getCause();
+ Assert.assertThat(cause, CoreMatchers.<Throwable>instanceOf(IOException.class));
+ }
+ }
+
+ @Test
+ public void testCustomSSLContext() throws Exception {
+ final SSLSetupHandler sslSetupHandler = new SSLSetupHandler() {
+
+ @Override
+ public void initalize(
+ final SSLEngine sslengine) throws SSLException {
+ }
+
+ @Override
+ public void verify(
+ final IOSession ioSession, final SSLSession sslsession) throws SSLException {
+ final BigInteger sslid = new BigInteger(sslsession.getId());
+ ioSession.setAttribute("ssl-id", sslid);
+ }
+
+ };
+
+ final HttpRequestHandler requestHandler = new HttpRequestHandler() {
+
+ @Override
+ public void handle(
+ final HttpRequest request,
+ final HttpResponse response,
+ final HttpContext context) throws HttpException, IOException {
+ final NHttpConnection conn = (NHttpConnection) context.getAttribute(
+ HttpCoreContext.HTTP_CONNECTION);
+ final BigInteger sslid = (BigInteger) conn.getContext().getAttribute(
+ "ssl-id");
+ Assert.assertNotNull(sslid);
+ }
+
+ };
+
+ this.server = new HttpServerNio();
+ this.server.setConnectionFactory(new ServerConnectionFactory(createServerSSLContext(), sslSetupHandler));
+ this.server.setTimeout(5000);
+ this.server.registerHandler("*", new BasicAsyncRequestHandler(requestHandler));
+ this.server.start();
+
+ this.client = new HttpClientNio(new BasicNIOConnFactory(new ClientConnectionFactory(createClientSSLContext()), null));
+ this.client.setTimeout(5000);
+ this.client.start();
+
+ final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
+ endpoint.waitFor();
+
+ final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
+
+ final HttpHost target = new HttpHost("localhost", address.getPort());
+ final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+ final Future<HttpResponse> future = this.client.execute(target, request);
+ final HttpResponse response = future.get(RESULT_TIMEOUT_SEC, TimeUnit.SECONDS);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+ }
+
+}