use of io.servicetalk.transport.api.ServerSslConfigBuilder in project servicetalk by apple.
the class GracefulConnectionClosureHandlingTest method setUp.
void setUp(HttpProtocol protocol, boolean initiateClosureFromClient, boolean useUds, boolean viaProxy) throws Exception {
this.protocol = protocol;
this.initiateClosureFromClient = initiateClosureFromClient;
if (useUds) {
Assumptions.assumeTrue(SERVER_CTX.ioExecutor().isUnixDomainSocketSupported(), "Server's IoExecutor does not support UnixDomainSocket");
Assumptions.assumeTrue(CLIENT_CTX.ioExecutor().isUnixDomainSocketSupported(), "Client's IoExecutor does not support UnixDomainSocket");
assumeFalse(viaProxy, "UDS cannot be used via proxy");
}
assumeFalse(protocol == HTTP_2 && viaProxy, "Proxy is not supported with HTTP/2");
HttpServerBuilder serverBuilder = (useUds ? forAddress(newSocketAddress()) : forAddress(localAddress(0))).protocols(protocol.config).ioExecutor(SERVER_CTX.ioExecutor()).executor(SERVER_CTX.executor()).executionStrategy(defaultStrategy()).enableWireLogging("servicetalk-tests-wire-logger", TRACE, () -> true).appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {
@Override
public Completable accept(final ConnectionContext context) {
if (!initiateClosureFromClient) {
((NettyConnectionContext) context).onClosing().whenFinally(onClosing::countDown).subscribe();
}
context.onClose().whenFinally(serverConnectionClosed::countDown).subscribe();
connectionAccepted.countDown();
return completed();
}
});
HostAndPort proxyAddress = null;
if (viaProxy) {
// Dummy proxy helps to emulate old intermediate systems that do not support half-closed TCP connections
proxyTunnel = new ProxyTunnel();
proxyAddress = proxyTunnel.startProxy();
serverBuilder.sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).build());
} else {
proxyTunnel = null;
}
serverContext = serverBuilder.listenBlockingStreamingAndAwait((ctx, request, response) -> {
serverReceivedRequest.countDown();
response.addHeader(CONTENT_LENGTH, valueOf(RESPONSE_CONTENT.length()));
serverSendResponse.await();
try (HttpPayloadWriter<String> writer = response.sendMetaData(RAW_STRING_SERIALIZER)) {
// Subscribe to the request payload body before response writer closes
BlockingIterator<Buffer> iterator = request.payloadBody().iterator();
// Consume request payload body asynchronously:
ctx.executionContext().executor().submit(() -> {
int receivedSize = 0;
while (iterator.hasNext()) {
Buffer chunk = iterator.next();
assert chunk != null;
receivedSize += chunk.readableBytes();
}
serverReceivedRequestPayload.add(receivedSize);
}).beforeOnError(cause -> {
LOGGER.error("failure while reading request", cause);
serverReceivedRequestPayload.add(-1);
}).toFuture();
serverSendResponsePayload.await();
writer.write(RESPONSE_CONTENT);
}
});
serverContext.onClose().whenFinally(serverContextClosed::countDown).subscribe();
client = (viaProxy ? forSingleAddress(serverHostAndPort(serverContext)).proxyAddress(proxyAddress).sslConfig(new ClientSslConfigBuilder(DefaultTestCerts::loadServerCAPem).peerHost(serverPemHostname()).build()) : forResolvedAddress(serverContext.listenAddress())).protocols(protocol.config).executor(CLIENT_CTX.executor()).ioExecutor(CLIENT_CTX.ioExecutor()).executionStrategy(defaultStrategy()).enableWireLogging("servicetalk-tests-wire-logger", TRACE, Boolean.TRUE::booleanValue).appendConnectionFactoryFilter(ConnectionFactoryFilter.withStrategy(cf -> initiateClosureFromClient ? new OnClosingConnectionFactoryFilter<>(cf, onClosing) : cf, ExecutionStrategy.offloadNone())).buildStreaming();
connection = client.reserveConnection(client.get("/")).toFuture().get();
connection.onClose().whenFinally(clientConnectionClosed::countDown).subscribe();
// wait until server accepts connection
connectionAccepted.await();
toClose = initiateClosureFromClient ? connection : serverContext;
}
use of io.servicetalk.transport.api.ServerSslConfigBuilder in project servicetalk by apple.
the class MutualSslTest method mutualSsl.
@ParameterizedTest
@MethodSource("params")
void mutualSsl(SslProvider serverSslProvider, SslProvider clientSslProvider, @SuppressWarnings("rawtypes") Map<SocketOption, Object> serverListenOptions, @SuppressWarnings("rawtypes") Map<SocketOption, Object> clientOptions) throws Exception {
assumeTcpFastOpen(clientOptions);
HttpServerBuilder serverBuilder = HttpServers.forAddress(localAddress(0)).sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).trustManager(DefaultTestCerts::loadClientCAPem).clientAuthMode(REQUIRE).provider(serverSslProvider).build());
for (@SuppressWarnings("rawtypes") Entry<SocketOption, Object> entry : serverListenOptions.entrySet()) {
@SuppressWarnings("unchecked") SocketOption<Object> option = entry.getKey();
serverBuilder.listenSocketOption(option, entry.getValue());
}
try (ServerContext serverContext = serverBuilder.listenBlockingAndAwait((ctx, request, responseFactory) -> responseFactory.ok());
BlockingHttpClient client = newClientBuilder(serverContext, clientOptions).sslConfig(new ClientSslConfigBuilder(DefaultTestCerts::loadServerCAPem).provider(clientSslProvider).peerHost(serverPemHostname()).keyManager(DefaultTestCerts::loadClientPem, DefaultTestCerts::loadClientKey).build()).buildBlocking()) {
assertEquals(HttpResponseStatus.OK, client.request(client.get("/")).status());
}
}
use of io.servicetalk.transport.api.ServerSslConfigBuilder in project servicetalk by apple.
the class SecureTcpTransportObserverErrorsTest method setUp.
private void setUp(ErrorReason errorReason, SslProvider clientProvider, SslProvider serverProvider) throws Exception {
ClientSslConfigBuilder clientSslBuilder = defaultClientSslBuilder(clientProvider);
ServerSslConfigBuilder serverSslBuilder = defaultServerSslBuilder(serverProvider);
switch(errorReason) {
case SECURE_CLIENT_TO_PLAIN_SERVER:
clientConfig.sslConfig(clientSslBuilder.build());
// In this scenario server may close the connection with or without an exception, depending on OS events
// Using CountDownLatch to verify that any of these two methods was invoked:
doAnswer(__ -> {
serverConnectionClosed.countDown();
return null;
// In most cases it closes with
// io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection reset by peer
}).when(serverConnectionObserver).connectionClosed(any(IOException.class));
doAnswer(__ -> {
serverConnectionClosed.countDown();
return null;
// But sometimes netty may close the connection before we generate StacklessClosedChannelException
// in io.servicetalk.transport.netty.internal.DefaultNettyConnection.channelInactive(...)
}).when(serverConnectionObserver).connectionClosed();
break;
case PLAIN_CLIENT_TO_SECURE_SERVER:
serverConfig.sslConfig(serverSslBuilder.build());
break;
case WRONG_HOSTNAME_VERIFICATION:
clientSslBuilder.hostnameVerificationAlgorithm("HTTPS");
clientSslBuilder.peerHost("foo");
clientConfig.sslConfig(clientSslBuilder.build());
serverConfig.sslConfig(serverSslBuilder.build());
break;
case UNTRUSTED_SERVER_CERTIFICATE:
clientSslBuilder = defaultClientSslBuilder(clientProvider, () -> null);
clientConfig.sslConfig(clientSslBuilder.build());
serverConfig.sslConfig(serverSslBuilder.build());
break;
case UNTRUSTED_CLIENT_CERTIFICATE:
clientSslBuilder.keyManager(DefaultTestCerts::loadClientPem, DefaultTestCerts::loadClientKey);
clientConfig.sslConfig(clientSslBuilder.build());
serverSslBuilder.clientAuthMode(REQUIRE);
serverConfig.sslConfig(serverSslBuilder.build());
break;
case MISSED_CLIENT_CERTIFICATE:
clientConfig.sslConfig(clientSslBuilder.build());
serverSslBuilder.clientAuthMode(REQUIRE);
serverConfig.sslConfig(serverSslBuilder.build());
break;
case NOT_MATCHING_PROTOCOLS:
clientSslBuilder.sslProtocols("TLSv1.2");
clientConfig.sslConfig(clientSslBuilder.build());
serverSslBuilder.sslProtocols("TLSv1.3");
serverConfig.sslConfig(serverSslBuilder.build());
break;
case NOT_MATCHING_CIPHERS:
clientSslBuilder.ciphers(singletonList("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"));
clientConfig.sslConfig(clientSslBuilder.build());
serverSslBuilder.ciphers(singletonList("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"));
serverConfig.sslConfig(serverSslBuilder.build());
break;
default:
throw new IllegalArgumentException("Unsupported ErrorSource: " + errorReason);
}
setUp();
}
use of io.servicetalk.transport.api.ServerSslConfigBuilder in project servicetalk by apple.
the class SslProvidersTest method setUp.
private void setUp(SslProvider serverSslProvider, SslProvider clientSslProvider, int payloadLength) throws Exception {
payloadBody = randomString(payloadLength);
serverContext = HttpServers.forAddress(localAddress(0)).sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).provider(serverSslProvider).build()).listenBlockingAndAwait((ctx, request, responseFactory) -> {
assertThat(ctx.sslSession(), is(notNullValue()));
assertThat(request.path(), is("/path"));
assertThat(request.headers().get(CONTENT_TYPE), is(TEXT_PLAIN_UTF_8));
assertThat(request.payloadBody(textSerializerUtf8()), is("request-payload-body-" + payloadBody));
return responseFactory.ok().payloadBody("response-payload-body-" + payloadBody, textSerializerUtf8());
});
client = HttpClients.forSingleAddress(serverHostAndPort(serverContext)).ioExecutor(NettyIoExecutors.createIoExecutor("client-io")).sslConfig(new ClientSslConfigBuilder(DefaultTestCerts::loadServerCAPem).peerHost(serverPemHostname()).provider(clientSslProvider).build()).buildBlocking();
}
use of io.servicetalk.transport.api.ServerSslConfigBuilder in project servicetalk by apple.
the class SslAndNonSslConnectionsTest method beforeClass.
@BeforeAll
static void beforeClass() throws Exception {
final HttpHeaders httpHeaders = DefaultHttpHeadersFactory.INSTANCE.newHeaders().set(CONTENT_LENGTH, ZERO);
// Configure HTTP server
when(STREAMING_HTTP_SERVICE.handle(any(), any(), any())).thenAnswer((Answer<Single<StreamingHttpResponse>>) invocation -> {
StreamingHttpResponseFactory factory = invocation.getArgument(2);
StreamingHttpResponse resp = factory.ok();
resp.headers().set(httpHeaders);
return succeeded(resp);
});
when(STREAMING_HTTP_SERVICE.closeAsync()).thenReturn(completed());
when(STREAMING_HTTP_SERVICE.closeAsyncGracefully()).thenReturn(completed());
serverCtx = HttpServers.forAddress(localAddress(0)).executionStrategy(offloadNever()).listenStreamingAndAwait(STREAMING_HTTP_SERVICE);
final String serverHostHeader = hostHeader(serverHostAndPort(serverCtx));
requestTarget = "http://" + serverHostHeader + "/";
// Configure HTTPS server
when(SECURE_STREAMING_HTTP_SERVICE.handle(any(), any(), any())).thenAnswer(invocation -> {
StreamingHttpResponseFactory factory = invocation.getArgument(2);
StreamingHttpResponse resp = factory.ok();
resp.headers().set(httpHeaders);
return succeeded(resp);
});
when(SECURE_STREAMING_HTTP_SERVICE.closeAsync()).thenReturn(completed());
when(SECURE_STREAMING_HTTP_SERVICE.closeAsyncGracefully()).thenReturn(completed());
secureServerCtx = HttpServers.forAddress(localAddress(0)).sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).build()).executionStrategy(offloadNever()).listenStreamingAndAwait(SECURE_STREAMING_HTTP_SERVICE);
final String secureServerHostHeader = hostHeader(serverHostAndPort(secureServerCtx));
secureRequestTarget = "https://" + secureServerHostHeader + "/";
}
Aggregations