> Therefore the HttpClient's default retry implementation does no longer retry Connection Resets happening while reading on an established connection, because all SSLException are excluded from retries.
I'm trying to understand exactly which failure mode is affected by the underlying change. I think you're describing the case where a connection reset occurs while the SSL handshake is being performed over an established TCP connection, and the desired retry behavior is to reconnect (over a new TCP connection) and negotiate TLS from scratch. Is this correct? On Thu, Jun 13, 2019 at 9:26 AM Eric Hubert <[email protected]> wrote: > Hi! > > Since using OpenJDK 11 I noticed a behavioral change in the default retry > handling of HttpClient for https URLs caused by an implementation change in > the JDK. > AFAIK until including OpenJDK 10 Java was throwing SocketException > directly for both Socket and SSLSocket implementatons when they occurred. > With OpenJDK 11 now Java wraps those in SSLExceptions. Prior OpenJDK > 11.0.3 the subclass SSLProtocolException was (mistakenly) used, resulting > in the following bug report: > https://bugs.openjdk.java.net/browse/JDK-8214339 > > After the fix with OpenJDK 11.0.3 / OpenJDK 12.0.1 it is still the base > class SSLException. Therefore the HttpClient's default retry implementation > does no longer retry Connection Resets happening while reading on an > established connection, because all SSLException are excluded from retries. > > Here an example of interesting stackframes for OpenJDK 11.0.3: > javax.net.ssl.SSLException: Connection reset > at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127) > at > java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321) > at > java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264) > at > java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259) > at > java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1314) > at > java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:839) > at org.apache.http.impl.io > .SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:139) > at org.apache.http.impl.io > .SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:155) > at org.apache.http.impl.io > .SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:284) > at > org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140) > > Thanks to the extensibility of HttpClient, it is quite easy to register an > own custom HttpRequestRetryHandler replacing the > DefaultHttpRequestRetryHandler to address the problem. > Now the question: What do others think - should the default implementation > be adjusted to also provide a behavior for OpenJDK >= 11 similar to those > of previous versions? > How could such a change look like? We now check the cause of SSLException. > > Additionally I have another question in the context of retry handling. > Wouldn't it be more flexible, if the retry logging will be moved from > org.apache.http.impl.execchain.RetryExec#execute to the actual RetryHandler > implementation? The INFO logging in RetryExec is already too much for some > users (they will likely set the level of the logger to WARN) but containing > too less context information for others. If the logging would be in the > RetryHandler implementation itself, custom implementations/sub classes > could adjust it to the specific requirements. What do others say? Maybe I'm > missing something here. > > Thanks, > Eric > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >
