diff options
Diffstat (limited to '0001-Remove-optional-dep-Blockhound.patch')
-rw-r--r-- | 0001-Remove-optional-dep-Blockhound.patch | 1177 |
1 files changed, 1177 insertions, 0 deletions
diff --git a/0001-Remove-optional-dep-Blockhound.patch b/0001-Remove-optional-dep-Blockhound.patch new file mode 100644 index 0000000..d870092 --- /dev/null +++ b/0001-Remove-optional-dep-Blockhound.patch @@ -0,0 +1,1177 @@ +From 36ea49fb9506d63fa4198b30b22bc33adc9c74d7 Mon Sep 17 00:00:00 2001 +From: Mat Booth <mat.booth@redhat.com> +Date: Mon, 7 Sep 2020 12:17:31 +0100 +Subject: [PATCH 1/4] Remove optional dep Blockhound + +--- + common/pom.xml | 5 - + .../java/io/netty/util/internal/Hidden.java | 200 ------ + ...ockhound.integration.BlockHoundIntegration | 14 - + pom.xml | 8 - + transport-blockhound-tests/pom.xml | 219 ------- + .../NettyBlockHoundIntegrationTest.java | 568 ------------------ + .../netty/util/internal/localhost_server.key | 28 - + .../netty/util/internal/localhost_server.pem | 17 - + .../io/netty/util/internal/mutual_auth_ca.pem | 19 - + 9 files changed, 1078 deletions(-) + delete mode 100644 common/src/main/java/io/netty/util/internal/Hidden.java + delete mode 100644 common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration + delete mode 100644 transport-blockhound-tests/pom.xml + delete mode 100644 transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java + delete mode 100644 transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key + delete mode 100644 transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem + delete mode 100644 transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem + +diff --git a/common/pom.xml b/common/pom.xml +index a70b4f3b18..eb83e339af 100644 +--- a/common/pom.xml ++++ b/common/pom.xml +@@ -82,11 +82,6 @@ + <artifactId>log4j-core</artifactId> + <scope>test</scope> + </dependency> +- <dependency> +- <groupId>io.projectreactor.tools</groupId> +- <artifactId>blockhound</artifactId> +- <optional>true</optional> +- </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> +diff --git a/common/src/main/java/io/netty/util/internal/Hidden.java b/common/src/main/java/io/netty/util/internal/Hidden.java +deleted file mode 100644 +index e227c90c7e..0000000000 +--- a/common/src/main/java/io/netty/util/internal/Hidden.java ++++ /dev/null +@@ -1,200 +0,0 @@ +-/* +- * Copyright 2019 The Netty Project +- * +- * The Netty Project licenses this file to you under the Apache License, +- * version 2.0 (the "License"); you may not use this file except in compliance +- * with the License. You may obtain a copy of the License at: +- * +- * https://www.apache.org/licenses/LICENSE-2.0 +- * +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +- * License for the specific language governing permissions and limitations +- * under the License. +- */ +- +-package io.netty.util.internal; +- +-import io.netty.util.concurrent.FastThreadLocalThread; +-import reactor.blockhound.BlockHound; +-import reactor.blockhound.integration.BlockHoundIntegration; +- +-import java.util.function.Function; +-import java.util.function.Predicate; +- +-/** +- * Contains classes that must have public visibility but are not public API. +- */ +-class Hidden { +- +- /** +- * This class integrates Netty with BlockHound. +- * <p> +- * It is public but only because of the ServiceLoader's limitations +- * and SHOULD NOT be considered a public API. +- */ +- @UnstableApi +- @SuppressJava6Requirement(reason = "BlockHound is Java 8+, but this class is only loaded by it's SPI") +- public static final class NettyBlockHoundIntegration implements BlockHoundIntegration { +- +- @Override +- public void applyTo(BlockHound.Builder builder) { +- builder.allowBlockingCallsInside( +- "io.netty.channel.nio.NioEventLoop", +- "handleLoopException" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.channel.kqueue.KQueueEventLoop", +- "handleLoopException" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.channel.epoll.EpollEventLoop", +- "handleLoopException" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.HashedWheelTimer", +- "start" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.HashedWheelTimer", +- "stop" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.HashedWheelTimer$Worker", +- "waitForNextTick" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.concurrent.SingleThreadEventExecutor", +- "confirmShutdown" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.buffer.PoolArena", +- "lock" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.buffer.PoolSubpage", +- "lock" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.buffer.PoolChunk", +- "allocateRun" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.buffer.PoolChunk", +- "free" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.buffer.AdaptivePoolingAllocator$1", +- "initialValue" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.buffer.AdaptivePoolingAllocator$1", +- "onRemoval" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.handler.ssl.SslHandler", +- "handshake" +- ); +- +- builder.allowBlockingCallsInside( +- "io.netty.handler.ssl.SslHandler", +- "runAllDelegatedTasks" +- ); +- builder.allowBlockingCallsInside( +- "io.netty.handler.ssl.SslHandler", +- "runDelegatedTasks" +- ); +- builder.allowBlockingCallsInside( +- "io.netty.util.concurrent.GlobalEventExecutor", +- "takeTask"); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.concurrent.GlobalEventExecutor", +- "addTask"); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.concurrent.SingleThreadEventExecutor", +- "takeTask"); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.concurrent.SingleThreadEventExecutor", +- "addTask"); +- +- builder.allowBlockingCallsInside( +- "io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback", +- "verify"); +- +- builder.allowBlockingCallsInside( +- "io.netty.handler.ssl.JdkSslContext$Defaults", +- "init"); +- +- // Let's whitelist SSLEngineImpl.unwrap(...) for now as it may fail otherwise for TLS 1.3. +- // See https://mail.openjdk.java.net/pipermail/security-dev/2020-August/022271.html +- builder.allowBlockingCallsInside( +- "sun.security.ssl.SSLEngineImpl", +- "unwrap"); +- +- builder.allowBlockingCallsInside( +- "sun.security.ssl.SSLEngineImpl", +- "wrap"); +- +- builder.allowBlockingCallsInside( +- "io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider", +- "parse"); +- +- builder.allowBlockingCallsInside( +- "io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider", +- "parseEtcResolverSearchDomains"); +- +- builder.allowBlockingCallsInside( +- "io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider", +- "parseEtcResolverOptions"); +- +- builder.allowBlockingCallsInside( +- "io.netty.resolver.HostsFileEntriesProvider$ParserImpl", +- "parse"); +- +- builder.allowBlockingCallsInside( +- "io.netty.util.NetUtil$SoMaxConnAction", +- "run"); +- +- builder.allowBlockingCallsInside("io.netty.util.internal.ReferenceCountUpdater", +- "retryRelease0"); +- +- builder.allowBlockingCallsInside("io.netty.util.internal.PlatformDependent", "createTempFile"); +- builder.nonBlockingThreadPredicate(new Function<Predicate<Thread>, Predicate<Thread>>() { +- @Override +- public Predicate<Thread> apply(final Predicate<Thread> p) { +- return new Predicate<Thread>() { +- @Override +- @SuppressJava6Requirement(reason = "Predicate#test") +- public boolean test(Thread thread) { +- return p.test(thread) || +- thread instanceof FastThreadLocalThread && +- !((FastThreadLocalThread) thread).permitBlockingCalls(); +- } +- }; +- } +- }); +- } +- +- @Override +- public int compareTo(BlockHoundIntegration o) { +- return 0; +- } +- } +-} +diff --git a/common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration b/common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration +deleted file mode 100644 +index e33bea796c..0000000000 +--- a/common/src/main/resources/META-INF/services/reactor.blockhound.integration.BlockHoundIntegration ++++ /dev/null +@@ -1,14 +0,0 @@ +-# Copyright 2019 The Netty Project +-# +-# The Netty Project licenses this file to you under the Apache License, +-# version 2.0 (the "License"); you may not use this file except in compliance +-# with the License. You may obtain a copy of the License at: +-# +-# https://www.apache.org/licenses/LICENSE-2.0 +-# +-# Unless required by applicable law or agreed to in writing, software +-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +-# License for the specific language governing permissions and limitations +-# under the License. +-io.netty.util.internal.Hidden$NettyBlockHoundIntegration +\ No newline at end of file +diff --git a/pom.xml b/pom.xml +index 0626fc25ec..5c5b5f8ef4 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -839,7 +839,6 @@ + <module>testsuite-native-image</module> + <module>testsuite-native-image-client</module> + <module>testsuite-native-image-client-runtime-init</module> +- <module>transport-blockhound-tests</module> + <module>microbench</module> + <module>bom</module> + </modules> +@@ -1254,13 +1253,6 @@ + <version>${log4j2.version}</version> + <scope>test</scope> + </dependency> +- +- <!-- BlockHound integration --> +- <dependency> +- <groupId>io.projectreactor.tools</groupId> +- <artifactId>blockhound</artifactId> +- <version>1.0.13.RELEASE</version> +- </dependency> + </dependencies> + </dependencyManagement> + +diff --git a/transport-blockhound-tests/pom.xml b/transport-blockhound-tests/pom.xml +deleted file mode 100644 +index d63f055214..0000000000 +--- a/transport-blockhound-tests/pom.xml ++++ /dev/null +@@ -1,219 +0,0 @@ +-<?xml version="1.0" encoding="UTF-8"?> +-<!-- +- ~ Copyright 2019 The Netty Project +- ~ +- ~ The Netty Project licenses this file to you under the Apache License, +- ~ version 2.0 (the "License"); you may not use this file except in compliance +- ~ with the License. You may obtain a copy of the License at: +- ~ +- ~ https://www.apache.org/licenses/LICENSE-2.0 +- ~ +- ~ Unless required by applicable law or agreed to in writing, software +- ~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +- ~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +- ~ License for the specific language governing permissions and limitations +- ~ under the License. +- --> +-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> +- +- <modelVersion>4.0.0</modelVersion> +- <parent> +- <groupId>io.netty</groupId> +- <artifactId>netty-parent</artifactId> +- <version>4.1.126.Final</version> +- </parent> +- +- <artifactId>netty-transport-blockhound-tests</artifactId> +- <packaging>jar</packaging> +- <description> +- Tests for the BlockHound integration. +- </description> +- +- <name>Netty/Transport/BlockHound/Tests</name> +- +- <profiles> +- <profile> +- <id>java13</id> +- <activation> +- <jdk>13</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java14</id> +- <activation> +- <jdk>14</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java15</id> +- <activation> +- <jdk>15</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java16</id> +- <activation> +- <jdk>16</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java17</id> +- <activation> +- <jdk>17</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java18</id> +- <activation> +- <jdk>18</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java19</id> +- <activation> +- <jdk>19</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java20</id> +- <activation> +- <jdk>20</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java21</id> +- <activation> +- <jdk>21</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java22</id> +- <activation> +- <jdk>22</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java23</id> +- <activation> +- <jdk>23</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java24</id> +- <activation> +- <jdk>24</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods</argLine.common> +- </properties> +- </profile> +- <profile> +- <id>java25</id> +- <activation> +- <jdk>25</jdk> +- </activation> +- <properties> +- <argLine.common>-XX:+AllowRedefinitionToAddDeleteMethods -XX:+EnableDynamicAgentLoading</argLine.common> +- </properties> +- </profile> +- </profiles> +- +- <properties> +- <maven.compiler.source>1.8</maven.compiler.source> +- <maven.compiler.target>1.8</maven.compiler.target> +- <!-- Needed for SelfSignedCertificate --> +- <argLine.java9.extras>--add-exports java.base/sun.security.x509=ALL-UNNAMED</argLine.java9.extras> +- <japicmp.skip>true</japicmp.skip> +- <!-- Do not deploy this module --> +- <skipDeploy>true</skipDeploy> +- <javaModuleName>io.netty.transport_blockhound_tests</javaModuleName> +- </properties> +- +- <dependencies> +- <dependency> +- <groupId>${project.groupId}</groupId> +- <artifactId>netty-transport</artifactId> +- <version>${project.version}</version> +- </dependency> +- <dependency> +- <groupId>${project.groupId}</groupId> +- <artifactId>netty-handler</artifactId> +- <version>${project.version}</version> +- </dependency> +- <dependency> +- <groupId>${project.groupId}</groupId> +- <artifactId>netty-resolver-dns</artifactId> +- <version>${project.version}</version> +- </dependency> +- <dependency> +- <groupId>${project.groupId}</groupId> +- <artifactId>${tcnative.artifactId}</artifactId> +- <classifier>${tcnative.classifier}</classifier> +- <optional>true</optional> +- </dependency> +- +- <dependency> +- <groupId>org.bouncycastle</groupId> +- <artifactId>bcpkix-jdk15on</artifactId> +- <optional>true</optional> +- </dependency> +- <dependency> +- <groupId>io.projectreactor.tools</groupId> +- <artifactId>blockhound</artifactId> +- <scope>test</scope> +- </dependency> +- <dependency> +- <groupId>org.junit.jupiter</groupId> +- <artifactId>junit-jupiter-api</artifactId> +- <scope>test</scope> +- </dependency> +- <dependency> +- <groupId>org.junit.jupiter</groupId> +- <artifactId>junit-jupiter-engine</artifactId> +- <scope>test</scope> +- </dependency> +- <dependency> +- <groupId>org.junit.jupiter</groupId> +- <artifactId>junit-jupiter-params</artifactId> +- <scope>test</scope> +- </dependency> +- <dependency> +- <groupId>org.assertj</groupId> +- <artifactId>assertj-core</artifactId> +- <scope>test</scope> +- </dependency> +- </dependencies> +-</project> +diff --git a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java b/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java +deleted file mode 100644 +index 403b97a418..0000000000 +--- a/transport-blockhound-tests/src/test/java/io/netty/util/internal/NettyBlockHoundIntegrationTest.java ++++ /dev/null +@@ -1,568 +0,0 @@ +-/* +- * Copyright 2019 The Netty Project +- +- * The Netty Project licenses this file to you under the Apache License, +- * version 2.0 (the "License"); you may not use this file except in compliance +- * with the License. You may obtain a copy of the License at: +- +- * https://www.apache.org/licenses/LICENSE-2.0 +- +- * Unless required by applicable law or agreed to in writing, software +- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +- * License for the specific language governing permissions and limitations +- * under the License. +- */ +-package io.netty.util.internal; +- +-import io.netty.bootstrap.Bootstrap; +-import io.netty.bootstrap.ServerBootstrap; +-import io.netty.buffer.ByteBuf; +-import io.netty.buffer.PooledByteBufAllocator; +-import io.netty.buffer.UnpooledByteBufAllocator; +-import io.netty.channel.Channel; +-import io.netty.channel.ChannelFuture; +-import io.netty.channel.ChannelFutureListener; +-import io.netty.channel.ChannelHandlerContext; +-import io.netty.channel.ChannelInboundHandlerAdapter; +-import io.netty.channel.ChannelInitializer; +-import io.netty.channel.EventLoopGroup; +-import io.netty.channel.nio.NioEventLoopGroup; +-import io.netty.channel.socket.nio.NioDatagramChannel; +-import io.netty.channel.socket.nio.NioServerSocketChannel; +-import io.netty.channel.socket.nio.NioSocketChannel; +-import io.netty.handler.ssl.SslContext; +-import io.netty.handler.ssl.SslContextBuilder; +-import io.netty.handler.ssl.SslHandler; +-import io.netty.handler.ssl.SslHandshakeCompletionEvent; +-import io.netty.handler.ssl.SslProvider; +-import io.netty.handler.ssl.util.InsecureTrustManagerFactory; +-import io.netty.handler.ssl.util.SelfSignedCertificate; +-import io.netty.resolver.dns.DnsNameResolverBuilder; +-import io.netty.resolver.dns.DnsServerAddressStreamProviders; +-import io.netty.util.HashedWheelTimer; +-import io.netty.util.ReferenceCountUtil; +-import io.netty.util.concurrent.DefaultThreadFactory; +-import io.netty.util.concurrent.EventExecutor; +-import io.netty.util.concurrent.FastThreadLocalThread; +-import io.netty.util.concurrent.GlobalEventExecutor; +-import io.netty.util.concurrent.ImmediateEventExecutor; +-import io.netty.util.concurrent.ImmediateExecutor; +-import io.netty.util.concurrent.ScheduledFuture; +-import io.netty.util.concurrent.SingleThreadEventExecutor; +-import io.netty.util.internal.Hidden.NettyBlockHoundIntegration; +-import org.junit.jupiter.api.BeforeAll; +-import org.junit.jupiter.api.Test; +-import org.junit.jupiter.api.Timeout; +-import reactor.blockhound.BlockHound; +-import reactor.blockhound.BlockingOperationError; +-import reactor.blockhound.integration.BlockHoundIntegration; +- +-import java.net.InetSocketAddress; +-import java.util.ArrayList; +-import java.util.List; +-import java.util.Queue; +-import java.util.ServiceLoader; +-import java.util.concurrent.Callable; +-import java.util.concurrent.CountDownLatch; +-import java.util.concurrent.ExecutionException; +-import java.util.concurrent.Executor; +-import java.util.concurrent.ExecutorService; +-import java.util.concurrent.Executors; +-import java.util.concurrent.Future; +-import java.util.concurrent.FutureTask; +-import java.util.concurrent.LinkedBlockingQueue; +-import java.util.concurrent.TimeUnit; +-import java.util.concurrent.atomic.AtomicLong; +-import java.util.concurrent.atomic.AtomicReference; +-import java.util.concurrent.locks.ReentrantLock; +- +-import static io.netty.buffer.Unpooled.wrappedBuffer; +-import static org.junit.jupiter.api.Assertions.assertEquals; +-import static org.junit.jupiter.api.Assertions.assertInstanceOf; +-import static org.junit.jupiter.api.Assertions.assertNull; +-import static org.junit.jupiter.api.Assertions.assertTrue; +-import static org.junit.jupiter.api.Assertions.fail; +-import static org.junit.jupiter.api.Assumptions.assumeTrue; +- +-public class NettyBlockHoundIntegrationTest { +- +- @BeforeAll +- public static void setUpClass() { +- BlockHound.install(); +- } +- +- @Test +- public void testServiceLoader() { +- for (BlockHoundIntegration integration : ServiceLoader.load(BlockHoundIntegration.class)) { +- if (integration instanceof NettyBlockHoundIntegration) { +- return; +- } +- } +- +- fail("NettyBlockHoundIntegration cannot be loaded with ServiceLoader"); +- } +- +- @Test +- public void testBlockingCallsInNettyThreads() throws Exception { +- final FutureTask<Void> future = new FutureTask<>(() -> { +- Thread.sleep(0); +- return null; +- }); +- GlobalEventExecutor.INSTANCE.execute(future); +- +- try { +- future.get(5, TimeUnit.SECONDS); +- fail("Expected an exception due to a blocking call but none was thrown"); +- } catch (ExecutionException e) { +- assertInstanceOf(BlockingOperationError.class, e.getCause()); +- } +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testGlobalEventExecutorTakeTask() throws InterruptedException { +- testEventExecutorTakeTask(GlobalEventExecutor.INSTANCE); +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testSingleThreadEventExecutorTakeTask() throws InterruptedException { +- SingleThreadEventExecutor executor = +- new SingleThreadEventExecutor(null, new DefaultThreadFactory("test"), true) { +- @Override +- protected void run() { +- while (!confirmShutdown()) { +- Runnable task = takeTask(); +- if (task != null) { +- task.run(); +- } +- } +- } +- }; +- testEventExecutorTakeTask(executor); +- } +- +- private static void testEventExecutorTakeTask(EventExecutor eventExecutor) throws InterruptedException { +- CountDownLatch latch = new CountDownLatch(1); +- ScheduledFuture<?> f = eventExecutor.schedule(latch::countDown, 10, TimeUnit.MILLISECONDS); +- f.sync(); +- latch.await(); +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testSingleThreadEventExecutorAddTask() throws Exception { +- TestLinkedBlockingQueue<Runnable> taskQueue = new TestLinkedBlockingQueue<>(); +- SingleThreadEventExecutor executor = +- new SingleThreadEventExecutor(null, new DefaultThreadFactory("test"), true) { +- @Override +- protected Queue<Runnable> newTaskQueue(int maxPendingTasks) { +- return taskQueue; +- } +- +- @Override +- protected void run() { +- while (!confirmShutdown()) { +- Runnable task = takeTask(); +- if (task != null) { +- task.run(); +- } +- } +- } +- }; +- taskQueue.emulateContention(); +- CountDownLatch latch = new CountDownLatch(1); +- executor.submit(() -> { +- executor.execute(() -> { }); // calls addTask +- latch.countDown(); +- }); +- taskQueue.waitUntilContented(); +- taskQueue.removeContention(); +- latch.await(); +- } +- +- @Test +- void permittingBlockingCallsInFastThreadLocalThreadSubclass() throws Exception { +- final FutureTask<Void> future = new FutureTask<>(() -> { +- Thread.sleep(0); +- return null; +- }); +- FastThreadLocalThread thread = new FastThreadLocalThread(future) { +- @Override +- public boolean permitBlockingCalls() { +- return true; // The Thread.sleep(0) call should not be flagged because we allow blocking calls. +- } +- }; +- thread.start(); +- future.get(5, TimeUnit.SECONDS); +- thread.join(); +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testHashedWheelTimerStartStop() throws Exception { +- HashedWheelTimer timer = new HashedWheelTimer(); +- Future<?> futureStart = GlobalEventExecutor.INSTANCE.submit(timer::start); +- futureStart.get(5, TimeUnit.SECONDS); +- Future<?> futureStop = GlobalEventExecutor.INSTANCE.submit(timer::stop); +- futureStop.get(5, TimeUnit.SECONDS); +- } +- +- // Tests copied from io.netty.handler.ssl.SslHandlerTest +- @Test +- public void testHandshakeWithExecutorThatExecuteDirectory() throws Exception { +- testHandshakeWithExecutor(Runnable::run, "TLSv1.2"); +- } +- +- @Test +- public void testHandshakeWithExecutorThatExecuteDirectoryTLSv13() throws Exception { +- assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK)); +- testHandshakeWithExecutor(Runnable::run, "TLSv1.3"); +- } +- +- @Test +- public void testHandshakeWithImmediateExecutor() throws Exception { +- testHandshakeWithExecutor(ImmediateExecutor.INSTANCE, "TLSv1.2"); +- } +- +- @Test +- public void testHandshakeWithImmediateExecutorTLSv13() throws Exception { +- assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK)); +- testHandshakeWithExecutor(ImmediateExecutor.INSTANCE, "TLSv1.3"); +- } +- +- @Test +- public void testHandshakeWithImmediateEventExecutor() throws Exception { +- testHandshakeWithExecutor(ImmediateEventExecutor.INSTANCE, "TLSv1.2"); +- } +- +- @Test +- public void testHandshakeWithImmediateEventExecutorTLSv13() throws Exception { +- assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK)); +- testHandshakeWithExecutor(ImmediateEventExecutor.INSTANCE, "TLSv1.3"); +- } +- +- @Test +- public void testHandshakeWithExecutor() throws Exception { +- ExecutorService executorService = Executors.newCachedThreadPool(); +- try { +- testHandshakeWithExecutor(executorService, "TLSv1.2"); +- } finally { +- executorService.shutdown(); +- } +- } +- +- @Test +- public void testHandshakeWithExecutorTLSv13() throws Exception { +- assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK)); +- ExecutorService executorService = Executors.newCachedThreadPool(); +- try { +- testHandshakeWithExecutor(executorService, "TLSv1.3"); +- } finally { +- executorService.shutdown(); +- } +- } +- +- @Test +- public void testTrustManagerVerifyJDK() throws Exception { +- testTrustManagerVerify(SslProvider.JDK, "TLSv1.2"); +- } +- +- @Test +- public void testTrustManagerVerifyTLSv13JDK() throws Exception { +- assumeTrue(SslProvider.isTlsv13Supported(SslProvider.JDK)); +- testTrustManagerVerify(SslProvider.JDK, "TLSv1.3"); +- } +- +- @Test +- public void testTrustManagerVerifyOpenSSL() throws Exception { +- testTrustManagerVerify(SslProvider.OPENSSL, "TLSv1.2"); +- } +- +- @Test +- public void testTrustManagerVerifyTLSv13OpenSSL() throws Exception { +- assumeTrue(SslProvider.isTlsv13Supported(SslProvider.OPENSSL)); +- testTrustManagerVerify(SslProvider.OPENSSL, "TLSv1.3"); +- } +- +- @Test +- public void testSslHandlerWrapAllowsBlockingCalls() throws Exception { +- final SslContext sslClientCtx = +- SslContextBuilder.forClient() +- .trustManager(InsecureTrustManagerFactory.INSTANCE) +- .sslProvider(SslProvider.JDK) +- .build(); +- final SslHandler sslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT); +- final EventLoopGroup group = new NioEventLoopGroup(); +- final CountDownLatch activeLatch = new CountDownLatch(1); +- final AtomicReference<Throwable> error = new AtomicReference<>(); +- +- Channel sc = null; +- Channel cc = null; +- try { +- sc = new ServerBootstrap() +- .group(group) +- .channel(NioServerSocketChannel.class) +- .childHandler(new ChannelInboundHandlerAdapter()) +- .bind(new InetSocketAddress(0)) +- .syncUninterruptibly() +- .channel(); +- +- cc = new Bootstrap() +- .group(group) +- .channel(NioSocketChannel.class) +- .handler(new ChannelInitializer<Channel>() { +- +- @Override +- protected void initChannel(Channel ch) { +- ch.pipeline().addLast(sslHandler); +- ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { +- +- @Override +- public void channelActive(ChannelHandlerContext ctx) { +- activeLatch.countDown(); +- } +- +- @Override +- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { +- if (evt instanceof SslHandshakeCompletionEvent && +- ((SslHandshakeCompletionEvent) evt).cause() != null) { +- Throwable cause = ((SslHandshakeCompletionEvent) evt).cause(); +- cause.printStackTrace(); +- error.set(cause); +- } +- ctx.fireUserEventTriggered(evt); +- } +- }); +- } +- }) +- .connect(sc.localAddress()) +- .addListener((ChannelFutureListener) future -> +- future.channel().writeAndFlush(wrappedBuffer(new byte [] { 1, 2, 3, 4 }))) +- .syncUninterruptibly() +- .channel(); +- +- assertTrue(activeLatch.await(5, TimeUnit.SECONDS)); +- assertNull(error.get()); +- } finally { +- if (cc != null) { +- cc.close().syncUninterruptibly(); +- } +- if (sc != null) { +- sc.close().syncUninterruptibly(); +- } +- group.shutdownGracefully(); +- ReferenceCountUtil.release(sslClientCtx); +- } +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void pooledBufferAllocation() throws Exception { +- AtomicLong iterationCounter = new AtomicLong(); +- PooledByteBufAllocator allocator = PooledByteBufAllocator.DEFAULT; +- FutureTask<Void> task = new FutureTask<>(() -> { +- List<ByteBuf> buffers = new ArrayList<>(); +- long count; +- do { +- count = iterationCounter.get(); +- } while (count == 0); +- for (int i = 0; i < 13; i++) { +- int size = 8 << i; +- buffers.add(allocator.ioBuffer(size, size)); +- } +- for (ByteBuf buffer : buffers) { +- buffer.release(); +- } +- return null; +- }); +- FastThreadLocalThread thread = new FastThreadLocalThread(task); +- thread.start(); +- do { +- allocator.dumpStats(); // This will take internal pool locks and we'll race with the thread. +- iterationCounter.set(1); +- } while (thread.isAlive()); +- thread.join(); +- task.get(); +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testUnixResolverDnsServerAddressStreamProvider_Parse() throws InterruptedException { +- doTestParseResolverFilesAllowsBlockingCalls(DnsServerAddressStreamProviders::unixDefault); +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testHostsFileParser_Parse() throws InterruptedException { +- doTestParseResolverFilesAllowsBlockingCalls(DnsNameResolverBuilder::new); +- } +- +- @Test +- @Timeout(value = 5000, unit = TimeUnit.MILLISECONDS) +- public void testUnixResolverDnsServerAddressStreamProvider_ParseEtcResolverSearchDomainsAndOptions() +- throws InterruptedException { +- NioEventLoopGroup group = new NioEventLoopGroup(); +- try { +- DnsNameResolverBuilder builder = new DnsNameResolverBuilder(group.next()) +- .datagramChannelFactory(NioDatagramChannel::new); +- doTestParseResolverFilesAllowsBlockingCalls(builder::build); +- } finally { +- group.shutdownGracefully(); +- } +- } +- +- private static void doTestParseResolverFilesAllowsBlockingCalls(Callable<Object> callable) +- throws InterruptedException { +- SingleThreadEventExecutor executor = +- new SingleThreadEventExecutor(null, new DefaultThreadFactory("test"), true) { +- @Override +- protected void run() { +- while (!confirmShutdown()) { +- Runnable task = takeTask(); +- if (task != null) { +- task.run(); +- } +- } +- } +- }; +- try { +- CountDownLatch latch = new CountDownLatch(1); +- List<Object> result = new ArrayList<>(); +- List<Throwable> error = new ArrayList<>(); +- executor.execute(() -> { +- try { +- result.add(callable.call()); +- } catch (Throwable t) { +- error.add(t); +- } +- latch.countDown(); +- }); +- latch.await(); +- assertEquals(0, error.size()); +- assertEquals(1, result.size()); +- } finally { +- executor.shutdownGracefully(); +- } +- } +- +- private static void testTrustManagerVerify(SslProvider provider, String tlsVersion) throws Exception { +- final SslContext sslClientCtx = +- SslContextBuilder.forClient() +- .sslProvider(provider) +- .protocols(tlsVersion) +- .trustManager(ResourcesUtil.getFile( +- NettyBlockHoundIntegrationTest.class, "mutual_auth_ca.pem")) +- .build(); +- +- final SslContext sslServerCtx = +- SslContextBuilder.forServer(ResourcesUtil.getFile( +- NettyBlockHoundIntegrationTest.class, "localhost_server.pem"), +- ResourcesUtil.getFile( +- NettyBlockHoundIntegrationTest.class, "localhost_server.key"), +- null) +- .sslProvider(provider) +- .protocols(tlsVersion) +- .build(); +- +- final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT); +- final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT); +- +- testHandshake(sslClientCtx, clientSslHandler, serverSslHandler); +- } +- +- private static void testHandshakeWithExecutor(Executor executor, String tlsVersion) throws Exception { +- final SslContext sslClientCtx = SslContextBuilder.forClient() +- .trustManager(InsecureTrustManagerFactory.INSTANCE) +- .sslProvider(SslProvider.JDK).protocols(tlsVersion).build(); +- +- final SelfSignedCertificate cert = new SelfSignedCertificate(); +- final SslContext sslServerCtx = SslContextBuilder.forServer(cert.key(), cert.cert()) +- .sslProvider(SslProvider.JDK).protocols(tlsVersion).build(); +- +- final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor); +- final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor); +- +- testHandshake(sslClientCtx, clientSslHandler, serverSslHandler); +- } +- +- private static void testHandshake(SslContext sslClientCtx, SslHandler clientSslHandler, +- SslHandler serverSslHandler) throws Exception { +- EventLoopGroup group = new NioEventLoopGroup(); +- Channel sc = null; +- Channel cc = null; +- try { +- sc = new ServerBootstrap() +- .group(group) +- .channel(NioServerSocketChannel.class) +- .childHandler(serverSslHandler) +- .bind(new InetSocketAddress(0)).syncUninterruptibly().channel(); +- +- ChannelFuture future = new Bootstrap() +- .group(group) +- .channel(NioSocketChannel.class) +- .handler(new ChannelInitializer<Channel>() { +- @Override +- protected void initChannel(Channel ch) { +- ch.pipeline() +- .addLast(clientSslHandler) +- .addLast(new ChannelInboundHandlerAdapter() { +- +- @Override +- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { +- if (evt instanceof SslHandshakeCompletionEvent && +- ((SslHandshakeCompletionEvent) evt).cause() != null) { +- ((SslHandshakeCompletionEvent) evt).cause().printStackTrace(); +- } +- ctx.fireUserEventTriggered(evt); +- } +- }); +- } +- }).connect(sc.localAddress()); +- cc = future.syncUninterruptibly().channel(); +- +- clientSslHandler.handshakeFuture().await().sync(); +- serverSslHandler.handshakeFuture().await().sync(); +- } finally { +- if (cc != null) { +- cc.close().syncUninterruptibly(); +- } +- if (sc != null) { +- sc.close().syncUninterruptibly(); +- } +- group.shutdownGracefully(); +- ReferenceCountUtil.release(sslClientCtx); +- } +- } +- +- private static class TestLinkedBlockingQueue<T> extends LinkedBlockingQueue<T> { +- +- private final ReentrantLock lock = new ReentrantLock(); +- +- @Override +- public boolean offer(T t) { +- lock.lock(); +- try { +- return super.offer(t); +- } finally { +- lock.unlock(); +- } +- } +- +- void emulateContention() { +- lock.lock(); +- } +- +- void waitUntilContented() throws InterruptedException { +- // wait until the lock gets contended +- while (lock.getQueueLength() == 0) { +- Thread.sleep(10L); +- } +- } +- +- void removeContention() { +- lock.unlock(); +- } +- } +-} +diff --git a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key b/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key +deleted file mode 100644 +index 9aa6611400..0000000000 +--- a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.key ++++ /dev/null +@@ -1,28 +0,0 @@ +------BEGIN PRIVATE KEY----- +-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDYrLtMlZzoe2BP +-iCURF3So5XNLfsOLcAVERXXjnxqX6Mex55WdJiy6uWTFKbRHWJdbWELdZxVl5+GX +-pMv3OdkKZt+19ZdSfByv6bB5RNdZOEGnKOHSY2XdnzYnF5JBaWEx0fvtvIPZOUlW +-DWgsQzJk1UQhu+XnBc7P1hHYNvwsVNOR+HD9LGebDy+UcfiL34XwAyBdHUsbcIr8 +-hltABcj6vNbqOLndpU86DxU9z9b1PDmkFVfisElhpDEhpxmTCwI22Us1GC8D81LM +-ZzMlbWSzTfNPEuqNzJYGiFt/XPwPkPPyVvti0XWPBQpwzJFFUX5xKsOGERolELRT +-0yNQYznFAgMBAAECggEAOFR/xSNITbB1k3ejm1PrwlUUqlXkZIXU+LDOO0UL1t5v +-vDKm1Not2sWECzYSZlID132UtJauG3YzUgdH95gUcv3XvyiAFLOriZhJht181vcn +-KlwYiWfJ/dn8bCFWpqbM2/TpeB8AcCLSjAqkQI2ftlMziUmeNXdvEt1mej2hRay1 +-ULfoxlC0mftNRQptD5gBFzrc47O4mVpVEQt4yS3Qyzp2/9ds9UkhaCIFpXPVCalZ +-ds7R+bDDP+wiYTkUcd8fvelaMkD3Wcy8DedGRShhILZvBYTDdWcpJ7+e5EkNlEq4 +-+Ys4Y/u6aFDJD53g3zCaJhatmdAZcct2MMmWH1vewQKBgQD3Y2S245cad1D9AqYD +-ChZGp95EfRo3EzXk4VkE50bjZXjHq9fD8T0CWEZGWQZrXJCR+vBpEURy0mrPD8se +-QQ0Q5+I27RadtfPnMd6ry9nDGMPxyd/10vzU6LazzLNE+uf9ljF1RHZu1iDAvInR +-r1cQGbn/wKBF6BurPPIXABZEuQKBgQDgN6JHbIfDzHKhwEoUTvRrYJsTXqplD+h0 +-Whg+kSQyhtKdlpINFOoEj8FUNJvTjG8les1aoajyWIqikVdvHto/mrxrSIeRkEmt +-X+KG+5ld2n466tzv1DmVcIGXSrBrH3lA0i6R8Ly26FLSqw0Z12fx5GUUa1qaVRqo +-rwcrIZovbQKBgHa2mojs9AC+Sv3uvG1u9LuZKJ7jDaZqMI2R2d7xgOH0Op5Ohy6+ +-39D1PVvasqroc3Op4J36rEcRVDHi2Uy+WJ/JNpO2+AhcXRuPodP88ZWel8C6aB+V +-zL/6oFntnAU5BgR5g2hLny2W0YbLsrMNmhDe15O0AvUo6cYla+K/pu/5AoGACr/g +-EdiMMcDthf+4DX0zjqpVBPq25J18oYdoPierOpjoJBIB8oqcJZfWxvi2t8+1zHA0 +-xDGX7fZ8vwqEzJkIEaCTg/k4NqxaO+uq6pnJYoyFHMIB0aW1FQsNy3kTOC+MGqV5 +-Ahoukf5VajA1MpX3L8upZO84qsmFu6yYhWLZB4kCgYBlgSD5G4q6rX4ELa3XG61h +-fDtu75IYEsjWm4vgJzHjeYT2xPIm9OFFYXjPghto0f1oH37ODD3DoXmsnmddgpmn +-tH7aRWWHsSpB5zVgftV4urNCIsm87LWw8mvUGgCwYV1CtCX8warKokfeoA2ltz4u +-oeuUzo98hN+aKRU5RO6Bmg== +------END PRIVATE KEY----- +diff --git a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem b/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem +deleted file mode 100644 +index 70759b29e5..0000000000 +--- a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/localhost_server.pem ++++ /dev/null +@@ -1,17 +0,0 @@ +------BEGIN CERTIFICATE----- +-MIICozCCAYsCAnS/MA0GCSqGSIb3DQEBDQUAMBgxFjAUBgNVBAMTDU5ldHR5VGVz +-dFJvb3QwIBcNMTcwMjE3MDMzMzQ0WhgPMjExNzAxMjQwMzMzNDRaMBQxEjAQBgNV +-BAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANis +-u0yVnOh7YE+IJREXdKjlc0t+w4twBURFdeOfGpfox7HnlZ0mLLq5ZMUptEdYl1tY +-Qt1nFWXn4Zeky/c52Qpm37X1l1J8HK/psHlE11k4Qaco4dJjZd2fNicXkkFpYTHR +-++28g9k5SVYNaCxDMmTVRCG75ecFzs/WEdg2/CxU05H4cP0sZ5sPL5Rx+IvfhfAD +-IF0dSxtwivyGW0AFyPq81uo4ud2lTzoPFT3P1vU8OaQVV+KwSWGkMSGnGZMLAjbZ +-SzUYLwPzUsxnMyVtZLNN808S6o3MlgaIW39c/A+Q8/JW+2LRdY8FCnDMkUVRfnEq +-w4YRGiUQtFPTI1BjOcUCAwEAATANBgkqhkiG9w0BAQ0FAAOCAQEAQNXnwE2MJFy5 +-ti07xyi8h/mY0Kl1dwZUqx4F9D9eoxLCq2/p3h/Z18AlOmjdW06pvC2sGtQtyEqL +-YjuQFbMjXRo9c+6+d+xwdDKTu7+XOTHvznJ8xJpKnFOlohGq/n3efBIJSsaeasTU +-slFzmdKYABDZzbsQ4X6YCIOF4XVdEQqmXpS+uEbn5C2sVtG+LXI8srmkVGpCcRew +-SuTGanwxLparhBBeN1ARjKzNxXUWuK2UKZ9p8c7n7TXGhd12ZNTcLhk4rCnOFq1J +-ySFvP5YL2q29fpEt+Tq0zm3V7An2qtaNDp26cEdevtKPjRyOLkCJx8OlZxc9DZvJ +-HjalFDoRUw== +------END CERTIFICATE----- +diff --git a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem b/transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem +deleted file mode 100644 +index 9c9241bc65..0000000000 +--- a/transport-blockhound-tests/src/test/resources/io/netty/util/internal/mutual_auth_ca.pem ++++ /dev/null +@@ -1,19 +0,0 @@ +------BEGIN CERTIFICATE----- +-MIIDLDCCAhSgAwIBAgIJAO1m5pioZhLLMA0GCSqGSIb3DQEBDQUAMBgxFjAUBgNV +-BAMTDU5ldHR5VGVzdFJvb3QwHhcNMTcwMjE3MDMzMzQ0WhcNMTcwMzE5MDMzMzQ0 +-WjAYMRYwFAYDVQQDEw1OZXR0eVRlc3RSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +-AQ8AMIIBCgKCAQEAnC7Y/p/TSWI1KxBKETfFKaRWCPEkoYn5G973WbCF0VDT90PX +-xK6yHvhqNdDQZPmddgfDAQfjekHeeIFkjCKlvQu0js0G4Bubz4NffNumd/Mgsix8 +-SWJ13lPk+Ly4PDv0bK1zB6BxP1qQm1qxVwsPy9zNP8ylJrM0Div4TXHmnWOfc0JD +-4/XPpfeUHH1tt/GMtsS2Gx6EpTVPD2w7LDKUza1/rQ7d9sqmFpgsNcI9Db/sAtFP +-lK2iJku5WIXQkmHimn4bqZ9wkiXJ85pm5ggGQqGMPSbe+2Lh24AvZMIBiwPbkjEU +-EDFXEJfKOC3Dl71JgWOthtHZ9vcCRDQ3Sky6AQIDAQABo3kwdzAdBgNVHQ4EFgQU +-qT+cH8qrebiVPpKCBQDB6At2iOAwSAYDVR0jBEEwP4AUqT+cH8qrebiVPpKCBQDB +-6At2iOChHKQaMBgxFjAUBgNVBAMTDU5ldHR5VGVzdFJvb3SCCQDtZuaYqGYSyzAM +-BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQCEemXTIew4pR2cHEFpVsW2 +-bLHXLAnC23wBMT46D3tqyxscukMYjFuWosCdEsgRW8d50BXy9o4dHWeg94+aDo3A +-DX4OTRN/veQGIG7dgM6poDzFuVJlSN0ubKKg6gpDD60IhopZpMviFAOsmzr7OXwS +-9hjbTqUWujMIEHQ95sPlQFdSaavYSFfqhSltWmVCPSbArxrw0lZ2QcnUqGN47EFp +-whc5wFB+rSw/ojU1jBLMvgvgzf/8V8zr1IBTDSiHNlknGqGpOOaookzUh95YRiAT +-hH82y9bBeflqroOeztqMpONpWoZjlz0sWbJNvXztXINL7LaNmVYOcoUrCcxPS54T +------END CERTIFICATE----- +-- +2.51.0 + |