//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.mortbay.jetty.alpn;
import java.net.InetSocketAddress;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.alpn.ALPN;
import org.junit.After;
import org.junit.Assert;
public class SSLSocketALPNTest extends AbstractALPNTest<SSLSocket>
{
private SSLServerSocket acceptor;
@After
public void dispose() throws Exception
{
if (acceptor != null)
acceptor.close();
}
@Override
protected SSLResult<SSLSocket> performTLSHandshake(SSLResult<SSLSocket> handshake, ALPN.ClientProvider clientProvider, final ALPN.ServerProvider serverProvider) throws Exception
{
SSLContext sslContext = handshake == null ? SSLSupport.newSSLContext() : handshake.context;
final CountDownLatch latch = new CountDownLatch(2);
final SSLResult<SSLSocket> sslResult = new SSLResult<>();
sslResult.context = sslContext;
final int readTimeout = 5000;
if (handshake == null)
{
acceptor = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket();
acceptor.bind(new InetSocketAddress("localhost", 0));
}
new Thread()
{
@Override
public void run()
{
try
{
SSLSocket serverSSLSocket = (SSLSocket)acceptor.accept();
System.err.println(serverSSLSocket);
sslResult.server = serverSSLSocket;
serverSSLSocket.setUseClientMode(false);
serverSSLSocket.setSoTimeout(readTimeout);
ALPN.put(serverSSLSocket, serverProvider);
serverSSLSocket.startHandshake();
latch.countDown();
}
catch (Exception x)
{
x.printStackTrace();
}
}
}.start();
SSLSocket clientSSLSocket = (SSLSocket)sslContext.getSocketFactory().createSocket("localhost", acceptor.getLocalPort());
sslResult.client = clientSSLSocket;
latch.countDown();
clientSSLSocket.setUseClientMode(true);
clientSSLSocket.setSoTimeout(readTimeout);
ALPN.put(clientSSLSocket, clientProvider);
clientSSLSocket.startHandshake();
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
return sslResult;
}
@Override
protected void performTLSClose(SSLResult<SSLSocket> sslResult) throws Exception
{
sslResult.client.close();
sslResult.server.close();
}
@Override
protected void performDataExchange(SSLResult<SSLSocket> sslResult) throws Exception
{
SSLSocket clientSSLSocket = sslResult.client;
SSLSocket serverSSLSocket = sslResult.server;
byte[] data = new byte[1024];
new Random().nextBytes(data);
// Write the data.
clientSSLSocket.getOutputStream().write(data);
// Read the data.
byte[] buffer = new byte[data.length];
int read = 0;
while (read < data.length)
read += serverSSLSocket.getInputStream().read(buffer);
// Write the data back.
serverSSLSocket.getOutputStream().write(buffer, 0, read);
// Read the echo.
read = 0;
while (read < data.length)
read += clientSSLSocket.getInputStream().read(buffer);
}
@Override
protected void performTLSRenegotiation(SSLResult<SSLSocket> sslResult, boolean client) throws Exception
{
if (client)
sslResult.client.startHandshake();
else
sslResult.server.startHandshake();
}
@Override
protected SSLSession getSSLSession(SSLResult<SSLSocket> sslResult, boolean client) throws Exception
{
SSLSocket sslSocket = client ? sslResult.client : sslResult.server;
return sslSocket.getSession();
}
}