reactor-netty: SpringBoot 2.4.2 BlockHound: blocking call when making outbound HTTPS request
Hello Reactor Netty Team,
During a test we were doing, we encountered an issue, and wanted to let you know. This blocking call only happens when making outbound (I am the client, making a request to another server) https call. And https is important, as it is not reproducible with http.
Here is the stack trace:
Caused by: reactor.blockhound.BlockingOperationError: Blocking call! java.io.FileInputStream#readBytes
at java.base/java.io.FileInputStream.readBytes(FileInputStream.java) ~[na:na]
at java.base/java.io.FileInputStream.read(FileInputStream.java:279) ~[na:na]
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.readFully(NativePRNG.java:424) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.ensureBufferValid(NativePRNG.java:526) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.implNextBytes(NativePRNG.java:545) ~[na:na]
at java.base/sun.security.provider.NativePRNG.engineNextBytes(NativePRNG.java:220) ~[na:na]
at java.base/java.security.SecureRandom.nextBytes(SecureRandom.java:741) ~[na:na]
at java.base/java.security.SecureRandom.next(SecureRandom.java:798) ~[na:na]
at java.base/java.util.Random.nextInt(Random.java:329) ~[na:na]
at java.base/sun.security.ssl.SSLContextImpl.engineInit(SSLContextImpl.java:117) ~[na:na]
at java.base/javax.net.ssl.SSLContext.init(SSLContext.java:297) ~[na:na]
at io.netty.handler.ssl.JdkSslClientContext.newSSLContext(JdkSslClientContext.java:294) ~[netty-handler-4.1.59.Final.jar:4.1.59.Final]
at io.netty.handler.ssl.JdkSslClientContext.<init>(JdkSslClientContext.java:272) ~[netty-handler-4.1.59.Final.jar:4.1.59.Final]
at io.netty.handler.ssl.SslContext.newClientContextInternal(SslContext.java:824) ~[netty-handler-4.1.59.Final.jar:4.1.59.Final]
at io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:614) ~[netty-handler-4.1.59.Final.jar:4.1.59.Final]
at reactor.netty.tcp.SslProvider.<init>(SslProvider.java:366) ~[reactor-netty-core-1.0.4.jar:1.0.4]
at reactor.netty.tcp.SslProvider.updateDefaultConfiguration(SslProvider.java:95) ~[reactor-netty-core-1.0.4.jar:1.0.4]
at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.lambda$subscribe$0(HttpClientConnect.java:234) ~[reactor-netty-http-1.0.4.jar:1.0.4]
at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57) ~[reactor-core-3.4.3.jar:3.4.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.3.jar:3.4.3]
at reactor.core.publisher.FluxRetryWhen.subscribe(FluxRetryWhen.java:76) ~[reactor-core-3.4.3.jar:3.4.3]
at reactor.core.publisher.MonoRetryWhen.subscribeOrReturn(MonoRetryWhen.java:46) ~[reactor-core-3.4.3.jar:3.4.3]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57) ~[reactor-core-3.4.3.jar:3.4.3]
at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:269) ~[reactor-netty-http-1.0.4.jar:1.0.4]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.3.jar:3.4.3]
May I ask what might be the root cause of this blocking call in a reactive stack for https please?
Thank you
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 20 (8 by maintainers)
@patpatpat123 With PR #1573, we exposed a new API that you can use in order to utilise the default configuration and also to solve the blocking call issue:
Examples
HTTP/1.1
HTTP/2
@rp199 with
.secure()
you eagerly initialise the defaultSslContext
, while without it the defaultSslContext
will be resolved lazy when there is a url withhttps
scheme.@rp199 In your use case, you expect the
HttpClient
to decide lazy based on the scheme whether you need security or not. Can you try the snippet below (it is in java, but the idea is important)@patpatpat123 Let’s keep this opened for the moment.
Thanks @violetagg, I can confirm that snippet works, I’m no longer getting any exception from blockhound and the https call is working fine 🙂
Just for sanity check, what was happening before was that if nothing is specified, the
HttpClient
will try to evaluate if we need security for the call and that’s where the blocking call was happening (that’s why it worked on http calls and not https). With that snippet, we enforced theHttpClient
to use security.But the end result is the same, ultimately the settings that we set would be the ones it would use if it decided for itself, right? If understand correctly, is just like a “shortcut” for the same result.
Thanks again for the help.