public void send(ByteBuffer appData)
{
if (closed.get())
{
throw new SenderException("SSL Sender is closed");
}
HandshakeStatus handshakeStatus;
Status status;
while(appData.hasRemaining())
{
int read = 0;
try
{
SSLEngineResult result = engine.wrap(appData, netData);
read = result.bytesProduced();
status = result.getStatus();
handshakeStatus = result.getHandshakeStatus();
}
catch(SSLException e)
{
throw new SenderException("SSL, Error occurred while encrypting data",e);
}
if(read > 0)
{
int limit = netData.limit();
netData.limit(netData.position());
netData.position(netData.position() - read);
ByteBuffer data = netData.slice();
netData.limit(limit);
netData.position(netData.position() + read);
delegate.send(data);
}
switch(status)
{
case CLOSED:
throw new SenderException("SSLEngine is closed");
case BUFFER_OVERFLOW:
netData.clear();
continue;
case OK:
break; // do nothing
default:
throw new IllegalStateException("SSLReceiver: Invalid State " + status);
}
switch (handshakeStatus)
{
case NEED_WRAP:
if (netData.hasRemaining())
{
continue;
}
case NEED_TASK:
doTasks();
break;
case NEED_UNWRAP:
flush();
synchronized(engineState)
{
switch (engine.getHandshakeStatus())
{
case NEED_UNWRAP:
long start = System.currentTimeMillis();
try
{
engineState.wait(timeout);
}
catch(InterruptedException e)
{
// pass
}
if (System.currentTimeMillis()- start >= timeout)
{
throw new SenderException(
"SSL Engine timed out waiting for a response." +
"To get more info,run with -Djavax.net.debug=ssl");
}
break;
}