Hi,
The proposed solution I gave in my previous mail wasn’t a very good idea because by setting the socket factory globally all other SSL clients are affected as well.
IMHO it isn’t a good practice at all to set such things globally. But it was the way to go with HttpsURLConnection :-)
Anyhow, because of this I chose to fix this another way without any configuration, see my pull request:
https://github.com/jersey/jersey/pull/111
Any feedback is as always welcome :-)
Thanks,
Roger
From: Marek Potociar <marek.potociar_at_oracle.com<mailto:marek.potociar_at_oracle.com>>
Reply-To: "users_at_jersey.java.net<mailto:users_at_jersey.java.net>" <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Date: Tuesday 23 September 2014 21:29
To: "users_at_jersey.java.net<mailto:users_at_jersey.java.net>" <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Subject: [Jersey] Re: JerseClient SSL/TLS connection reuse
Hi Robert,
Your suggestion seems to make sense, just please, make sure you add the new property to the HttpUrlConnectorProvider instead of ClientProperties as the property is connector-specific.
Cheers,
Marek
On 22 Sep 2014, at 17:44, Roger Nordquist <roger.nordquist_at_valtech.se<mailto:roger.nordquist_at_valtech.se>> wrote:
Ok, it seems I found the reason why the connection reuse doesn’t work.
Jersey HttpUrlConnector always recreates the SSLSocketFactory for the HttpsURLConnection on each request.
I’m not sure why this is needed, if it has something to do with client reuse for different hosts or so?
However, I think there should be a possibility to configure this. My suggestion is to add a property that makes Jersey client reuse the global sslSocketFactory set by: HttpsURLConnection.setDefaultSSLSocketFactory.
Something like this:
if (request.resolveProperty(ClientProperties.USE_GLOBAL_SSL_SOCKET_FACTORY, false)) {
suc.setSSLSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
} else {
suc.setSSLSocketFactory(client.getSslContext().getSocketFactory());
}
What do you think? Any feedback is welcome!
I will probably come up with a pull request in the next couple of days.
Regards,
Roger
From: Roger Nordquist <roger.nordquist_at_valtech.se<mailto:roger.nordquist_at_valtech.se>>
Reply-To: "users_at_jersey.java.net<mailto:users_at_jersey.java.net>" <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Date: Friday 19 September 2014 12:39
To: "users_at_jersey.java.net<mailto:users_at_jersey.java.net>" <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Subject: [Jersey] JerseClient SSL/TLS connection reuse
(New subject)
Hello,
I’m in need of help to get JerseyClient to reuse connections when using SSL.
We use a client certificate with a truststore (see SSL config code in forwarded mail below)
The application we’ve built integrates with a system on the other side of the Atlantic and the latency is too high if the SSL handshake needs to take place each and every time a request is made.
I’ve looked through all guides and recommendations I’ve found on the internet in configuring the client correctly and checked with this page that we do it correctly.
http://docs.oracle.com/javase/8/docs/technotes/guides/net/http-keepalive.html
The question is if Jersey follows all that specification?
The server we access returns Connection: Keep-Alive and Keep-Alive: timeout=15, max=100 but the client recreates the connection anyway.
The response code is 200 and we read the response fully.
We have managed to get the reuse working with ApacheConnector (after some minor modification) but we haven’t found anyway of doing it with “vanilla” Jersey as we would like it to be.
Thanks,
Roger
From: Roger Nordquist <roger.nordquist_at_valtech.se<mailto:roger.nordquist_at_valtech.se>>
Date: Wednesday 10 September 2014 14:30
To: "users_at_jersey.java.net<mailto:users_at_jersey.java.net>" <users_at_jersey.java.net<mailto:users_at_jersey.java.net>>
Subject: JettyConnector using Proxy over SSL/TLS
Hello,
I am trying to use JettyConnectorProvider in Jersey 2.8 to make requests to a resource behind a proxy using SSL.
The reason why I chosen to replace the default provider is because the default one doesn’t seem to reuse connections according to the setting in the Keep-Alive header as we need it to do.
It’s for performance reasons really, but I can’t get it to work through the proxy.
Here is my setup:
SslConfigurator sslConfig = SslConfigurator
.newInstance()
.trustStore(config.getTrustStore())
.trustManagerFactoryAlgorithm(“SunX509")
.keyPassword(config.getKeystorePass())
.keyManagerFactoryAlgorithm(“SunX509")
.keyStore(keyStore);
ClientConfig clientConfig = new ClientConfig();
clientConfig.connectorProvider(new JettyConnectorProvider());
clientConfig.property(JettyClientProperties.SSL_CONFIG, sslConfig);
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, config.getConnectTimeout());
clientConfig.property(ClientProperties.READ_TIMEOUT, config.getReadTimeout());
if (config.usingHttpProxy()) {
clientConfig.property(ClientProperties.PROXY_URI, String.format("
http://%s:%s", config.getHttpProxyHost(), config.getHttpProxyPort()));
}
return ClientBuilder.newBuilder()
.withConfig(clientConfig)
.build()
.register(getJacksonConfiguration())
.register(new LoggingFilter())
.register(new CharacterSetFilter())
.register(new RequestTimeLogging());
The exception I get when using the proxy is the following:
java.nio.channels.ReadPendingException: null
at org.eclipse.jetty.io.FillInterest.register(FillInterest.java:62) ~[jetty-io-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at org.eclipse.jetty.io.AbstractEndPoint.fillInterested(AbstractEndPoint.java:119) ~[jetty-io-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at org.eclipse.jetty.io.AbstractConnection$FillInterestedState.onEnter(AbstractConnection.java:269) ~[jetty-io-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at org.eclipse.jetty.io.AbstractConnection.next(AbstractConnection.java:238) ~[jetty-io-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:512) ~[jetty-io-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) ~[jetty-util-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) ~[jetty-util-9.1.1.v20140108.jar:3.19.0-SNAPSHOT]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_05]
2014-09-09 18:02:51,131 ExceptionMapper:24:ERROR - Uncaught exception occurred. - POST /resource …
javax.ws.rs.ProcessingException: java.util.concurrent.ExecutionException: java.io.EOFException
at org.glassfish.jersey.jetty.connector.JettyConnector.apply(JettyConnector.java:277) ~[jersey-jetty-connector-2.8.jar:na]
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:224) ~[jersey-client-2.8.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:655) ~[jersey-client-2.8.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:652) ~[jersey-client-2.8.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:228) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:652) ~[jersey-client-2.8.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:412) ~[jersey-client-2.8.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:321) ~[jersey-client-2.8.jar:na]
...
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_05]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_05]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_05]
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:269) ~[jersey-server-2.8.jar:na]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297) [jersey-common-2.8.jar:na]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:252) [jersey-server-2.8.jar:na]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1023) [jersey-server-2.8.jar:na]
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372) [jersey-container-servlet-core-2.8.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:382) [jersey-container-servlet-core-2.8.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:345) [jersey-container-servlet-core-2.8.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:220) [jersey-container-servlet-core-2.8.jar:na]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751) []
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1666) []
...
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1645) []
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:564) []
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) []
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578) []
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221) []
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111) []
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498) []
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183) []
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045) []
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) []
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98) []
at org.eclipse.jetty.server.Server.handle(Server.java:461) []
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284) []
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244) []
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534) []
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) []
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) []
at java.lang.Thread.run(Unknown Source) [na:1.8.0_05]
Caused by: java.util.concurrent.ExecutionException: java.io.EOFException
at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118) ~[jetty-client-9.1.1.v20140108.jar:9.1.1.v20140108]
at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:110) ~[jetty-client-9.1.1.v20140108.jar:9.1.1.v20140108]
at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:579) ~[jetty-client-9.1.1.v20140108.jar:9.1.1.v20140108]
at org.glassfish.jersey.jetty.connector.JettyConnector.apply(JettyConnector.java:259) ~[jersey-jetty-connector-2.8.jar:na]
... 68 common frames omitted
Caused by: java.io.EOFException: null
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.earlyEOF(HttpReceiverOverHTTP.java:203) ~[]
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1261) ~[]
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.shutdown(HttpReceiverOverHTTP.java:129) ~[]
at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:91) ~[]
at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:75) ~[]
at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:103) ~[]
at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:505) ~[]
... 3 common frames omitted
It looks like it cannot read the response properly but it only happens with the JettyConnector, not the default so I think the proxy is correctly configured.
When not using the proxy it looks like it works perfectly and connections are reused as I want them to, but I can’t say for sure for those tests were only made from my local computer, not the environment I get this exception on.
And btw, we are not using any asynchronous calls so this exception is kinda confusing :S
Is some additional configuration needed that I’m not aware of?
Any idea´s and pointers are welcome as I’m pretty stuck right now! :)
Thanks!
/Roger