Hi Alexey, Hi Ryan
First, thanks a lot for all your help. I really appreciate.
I understand now that prior to version 2.1.2 the call Response.getOutputStream() was non-blocking, so the behavior hasn't change. My mistake, sorry.
I wrote a quick test in attachment to show you what's happen in Grizzly 2.1.2.
It's a fully Maven project.
PS : If you look at the class DownloadHandler, you will see that it "simulate" more or less an async behavior. I know it's not good with Grizzly 2, but it's what we put in place for Grizzly 1.9.x. This is only to illustrate the problem.
PS2 : I made a mistake in my previous mail, I have modify the Jersey connector to use the blocking mode : so getOutputStream( true ) (and not false, I'm always confuse between sync/async/blocking/non-blocking .... Sorry)
Let's do the test :
1- Non SSL case with getOuputStream( true )
Start the class com.acme.Main
Use your favorite browser and type
http://localhost:35000/www/BOF-4989-Grizzly.pdf
It works.
2- Non SSL case with getOutputStream()
Modify the class com.acme.download.Download to use non-blocking : this.os = res.getOutputStream();
Type
http://localhost:35000/www/BOF-4989-Grizzly.pdf
It works
3- SSL case with getOutputStream( true );
Uncomment the SSL activation in the class com.acme.Main
Modify the class com.acme.download.Download to use blocking : this.os = res.getOutputStream( true );
Type
https://localhost:35000/www/BOF-4989-Grizzly.pdf
It works
4- SSL case with getOutputStream();
Modify the class com.acme.download.Download to use non-blocking : this.os = res.getOutputStream();
Type
https://localhost:35000/www/BOF-4989-Grizzly.pdf
It doesn't work :-(
I have this stack trace :
ATTENTION: Exception during FilterChain execution
org.glassfish.grizzly.TransformationException: javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at org.glassfish.grizzly.ssl.SSLDecoderTransformer.transformImpl(SSLDecoderTransformer.java:175)
at org.glassfish.grizzly.ssl.SSLDecoderTransformer.transformImpl(SSLDecoderTransformer.java:66)
at org.glassfish.grizzly.AbstractTransformer.transform(AbstractTransformer.java:73)
at org.glassfish.grizzly.filterchain.AbstractCodecFilter.handleRead(AbstractCodecFilter.java:71)
at org.glassfish.grizzly.ssl.SSLFilter.handleRead(SSLFilter.java:176)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:286)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:223)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:155)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:134)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:827)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:103)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:111)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:131)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:508)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:488)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1429)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1397)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1563)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1023)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:837)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:713)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:607)
at org.glassfish.grizzly.ssl.SSLDecoderTransformer.transformImpl(SSLDecoderTransformer.java:127)
... 18 more
So, what's was confusing for me was that without SSL enable, there is no problem if you use getOutputStream( true/false )
And with Jersey, everything seems to work until you enable SSL because by default the Grizzly Jersey connector use getOutputStream()
Hope it helps
Thank and regards
David
From: Oleksiy Stashok [mailto:oleksiy.stashok_at_oracle.com]
Sent: lundi 12 septembre 2011 19:05
To: users_at_grizzly.java.net
Subject: Re: Grizzly 2 and SSL
Hi David,
While writing a simple test case this afternoon, I found what was wrong.
The main problem was the usage of Response.getOutputStream().
This is my understanding :
Before Grizzly 2.1.2, there were only 1 method : Response.getOutputStream().
AFAIU : This method return a blocking stream.
AFAIR it was non-blocking :)
But from Grizzly 2.1.2, they are 2 methods :
Response.getOutputStream() and Response.getOutputStream( Boolean blocking )
The problem is that Response.getOutputStream() call the method Response.getOutputStream( false ); and it change the behavior comparing to the previous Grizzly version. Do you agree ?
We added ability to retrieve blocking OutputStream. Earlier it was non-blocking only.
But, I also use Jersey, and I had problem with it.
And basically the problem is the same, in Jersey 1.9, the Grizzly 2 connector use the method getOutputStream() and I have the same problem.
I quickly rewrite the Jersey connector by putting getOutputStream( false ) in the Jersey writer and now it works !
Is it really wanted to put the Jersey connector in non blocking mode ? I feel it's a mistake bug. But I may be wrong.
That's very interesting, can you pls. give us a testcase? :)) Don't understand why the mode of output stream makes any difference.
I don't know if it's normal/ok to assert that the non blocking mode is enable by default.
It's probably not. We're going to refactor this part of code and separate methods, which return blocking and non-blocking streams.
We even have issue to track this:
http://java.net/jira/browse/GRIZZLY-1070
For me it's an advanced feature and should be enabled only by using the getOutputStream( Boolean blocking ) method.
Agree.
Thanks.
WBR,
Alexey.
From: Oleksiy Stashok [mailto:oleksiy.stashok_at_oracle.com]
Sent: vendredi 9 septembre 2011 18:53
To: users_at_grizzly.java.net<mailto:users_at_grizzly.java.net>
Subject: Re: Grizzly 2 and SSL
Hi David,
I believe it's something configuration related.
Can you pls. send us a testcase to reproduce the issue?
Thanks.
WBR,
Alexey.
On 09/09/2011 04:15 PM, Gay David (Annecy) wrote:
Hi all,
I'm using Grizzly 2.1.2 and I have a problem when turning on SLL. I have this exception :
2011-09-09 15:59:23,697 GMT+0200 - [Grizzly(1)] WARN (DefaultFilterChain.execute:177) - Exception during FilterChain execution
org.glassfish.grizzly.TransformationException: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
at org.glassfish.grizzly.ssl.SSLDecoderTransformer.transformImpl(SSLDecoderTransformer.java:175)
at org.glassfish.grizzly.ssl.SSLDecoderTransformer.transformImpl(SSLDecoderTransformer.java:66)
at org.glassfish.grizzly.AbstractTransformer.transform(AbstractTransformer.java:73)
at org.glassfish.grizzly.filterchain.AbstractCodecFilter.handleRead(AbstractCodecFilter.java:71)
at org.glassfish.grizzly.ssl.SSLFilter.handleRead(SSLFilter.java:176)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:286)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:223)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:155)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:134)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:827)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:103)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:111)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:131)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:508)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:488)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1429)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1397)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1563)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1023)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:837)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:713)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:607)
at org.glassfish.grizzly.ssl.SSLDecoderTransformer.transformImpl(SSLDecoderTransformer.java:127)
... 18 more
And this is the code I use to init the SSL in Grizzly :
private static final String SSLCTX_TLS = "TLS";
private static final String KSTYPE_PKCS12 = "PKCS12";
public void startServer( SomeConfigurationObject conf ) throws Exception
{
...
HttpServer server = new HttpServer();
NetworkListener nl = new NetworkListener( identifier, host, port );
if( useSsl )
{
nl.setSecure( true );
nl.setSSLEngineConfig( createSSLConfiguration(conf) );
}
nl.setRcmSupportEnabled( false );
nl.setCompression( "on" );
nl.setChunkingEnabled( true );
nl.setDisableUploadTimeout( true );
nl.getFileCache().setEnabled( false );
server.addListener( nl );
// Add the http handlers
....
// Start
server.start();
}
private SSLEngineConfigurator createSSLConfiguration( SomeConfigurationObject conf ) throws IOException
{
ByteArrayInputStream bais;
KeyStore ks;
KeyManagerFactory kmFactory;
SSLContext sslContext;
SSLEngineConfigurator engineConf;
engineConf = null;
try
{
// Prepare a key manager using the provided keystore
kmFactory = KeyManagerFactory.getInstance( KeyManagerFactory.getDefaultAlgorithm() );
// .... some code to init the KeyManagerFactory
// Initialize the SSL context with the certificate as the server identity
sslContext = SSLContext.getInstance( SSLCTX_TLS );
sslContext.init( kmFactory.getKeyManagers(), null, null );
// Create the engine conf
engineConf = new SSLEngineConfigurator( sslContext, false, false, false );
engineConf.setEnabledProtocols( new String[] { "TLSv1", "SSLv3" } );
engineConf.setProtocolConfigured( true );
engineConf.setEnabledCipherSuites( conf.getEnabledCipherSuites() );
engineConf.setCipherConfigured( true );
}
catch( ... ) { .... }
Did someone have a clue of what's could be wrong ?
Thanks and regards
David