Skip to content

Commit

Permalink
Expose SslConfig through ConnectionInfo
Browse files Browse the repository at this point in the history
Motivation:

`SSLSession` represents the result of SSL negotiation. However, it's
useful to know what `SslConfig` was used to establish the session for
observability or runtime checks.

Modifications:

- Add `ConnectionInfo#sslConfig()` method;
- Propagate `SslConfig` to all `ConnectionInfo` implementations;
- Adjust tests;

Result:

Users have access to `SslConfig` from service or connection
factory/filter.
  • Loading branch information
idelpivnitskiy committed Mar 18, 2022
1 parent ce70bdd commit b802c8c
Show file tree
Hide file tree
Showing 30 changed files with 241 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.http.api.HttpProtocolVersion;
import io.servicetalk.transport.api.ExecutionContext;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.FlushStrategies;
import io.servicetalk.transport.netty.internal.FlushStrategy;
import io.servicetalk.transport.netty.internal.GlobalExecutionContext;
Expand Down Expand Up @@ -232,6 +233,12 @@ public SocketAddress remoteAddress() {
return new InetSocketAddress(0);
}

@Nullable
@Override
public SslConfig sslConfig() {
return null;
}

@Nullable
@Override
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.servicetalk.http.api.HttpProtocolVersion;
import io.servicetalk.http.api.HttpServiceContext;
import io.servicetalk.transport.api.ConnectionContext;
import io.servicetalk.transport.api.SslConfig;

import java.net.SocketAddress;
import java.net.SocketOption;
Expand Down Expand Up @@ -56,6 +57,12 @@ public SocketAddress remoteAddress() {
return connectionContext.remoteAddress();
}

@Nullable
@Override
public SslConfig sslConfig() {
return connectionContext.sslConfig();
}

@Override
@Nullable
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.servicetalk.serializer.api.StreamingSerializer;
import io.servicetalk.serializer.utils.FramedDeserializerOperator;
import io.servicetalk.transport.api.IoExecutor;
import io.servicetalk.transport.api.SslConfig;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
Expand Down Expand Up @@ -165,6 +166,12 @@ public SocketAddress remoteAddress() {
return InMemorySocketAddress.INSTANCE;
}

@Nullable
@Override
public SslConfig sslConfig() {
return null;
}

@Nullable
@Override
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.servicetalk.http.api;

import io.servicetalk.concurrent.api.Completable;
import io.servicetalk.transport.api.SslConfig;

import java.net.SocketAddress;
import java.net.SocketOption;
Expand Down Expand Up @@ -64,6 +65,12 @@ public SocketAddress remoteAddress() {
return delegate.remoteAddress();
}

@Nullable
@Override
public SslConfig sslConfig() {
return delegate.sslConfig();
}

@Override
@Nullable
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.servicetalk.http.api;

import io.servicetalk.concurrent.api.Completable;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.AddressUtils;

import java.net.SocketAddress;
Expand Down Expand Up @@ -71,6 +72,12 @@ public SocketAddress remoteAddress() {
return remoteAddress;
}

@Nullable
@Override
public SslConfig sslConfig() {
return null;
}

@Nullable
@Override
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ private Single<FilterableStreamingHttpConnection> createConnection(
assert h2Config != null;
return H2ClientParentConnectionContext.initChannel(channel, executionContext,
h2Config, reqRespFactoryFunc.apply(HttpProtocolVersion.HTTP_2_0), tcpConfig.flushStrategy(),
tcpConfig.idleTimeoutMs(), new H2ClientParentChannelInitializer(h2Config),
tcpConfig.idleTimeoutMs(), tcpConfig.sslConfig(),
new H2ClientParentChannelInitializer(h2Config),
connectionObserver, config.allowDropTrailersReadFromTransport());
default:
return failed(new IllegalStateException("Unknown ALPN protocol negotiated: " + protocol));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import io.servicetalk.transport.api.ConnectionObserver.MultiplexedObserver;
import io.servicetalk.transport.api.ConnectionObserver.StreamObserver;
import io.servicetalk.transport.api.IoThreadFactory;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.ChannelInitializer;
import io.servicetalk.transport.netty.internal.CloseHandler;
import io.servicetalk.transport.netty.internal.DefaultNettyConnection;
Expand Down Expand Up @@ -93,8 +94,9 @@
final class H2ClientParentConnectionContext extends H2ParentConnectionContext {
private H2ClientParentConnectionContext(Channel channel, HttpExecutionContext executionContext,
FlushStrategy flushStrategy, @Nullable Long idleTimeoutMs,
@Nullable final SslConfig sslConfig,
final KeepAliveManager keepAliveManager) {
super(channel, executionContext, flushStrategy, idleTimeoutMs, keepAliveManager);
super(channel, executionContext, flushStrategy, idleTimeoutMs, sslConfig, keepAliveManager);
}

interface H2ClientParentConnection extends FilterableStreamingHttpConnection, NettyConnectionContext {
Expand All @@ -105,6 +107,7 @@ static Single<H2ClientParentConnection> initChannel(Channel channel, HttpExecuti
StreamingHttpRequestResponseFactory reqRespFactory,
FlushStrategy parentFlushStrategy,
@Nullable Long idleTimeoutMs,
@Nullable SslConfig sslConfig,
ChannelInitializer initializer,
ConnectionObserver observer,
boolean allowDropTrailersReadFromTransport) {
Expand All @@ -118,7 +121,7 @@ protected void handleSubscribe(final Subscriber<? super H2ClientParentConnection
delayedCancellable = new DelayedCancellable();
KeepAliveManager keepAliveManager = new KeepAliveManager(channel, config.keepAlivePolicy());
H2ClientParentConnectionContext connection = new H2ClientParentConnectionContext(channel,
executionContext, parentFlushStrategy, idleTimeoutMs,
executionContext, parentFlushStrategy, idleTimeoutMs, sslConfig,
keepAliveManager);
channel.attr(CHANNEL_CLOSEABLE_KEY).set(connection);
// We need the NettyToStChannelInboundHandler to be last in the pipeline. We accomplish that by
Expand Down Expand Up @@ -354,6 +357,7 @@ private void childChannelActive(Future<Http2StreamChannel> future,
parentContext.flushStrategyHolder.currentStrategy(),
parentContext.idleTimeoutMs,
HTTP_2_0,
parentContext.sslConfig(),
parentContext.sslSession(),
parentContext.nettyChannel().config(),
streamObserver,
Expand Down Expand Up @@ -412,6 +416,12 @@ public SocketAddress remoteAddress() {
return parentContext.remoteAddress();
}

@Nullable
@Override
public SslConfig sslConfig() {
return parentContext.sslConfig();
}

@Nullable
@Override
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Single<FilterableStreamingHttpConnection> newFilterableConnection(
return TcpConnector.connect(null, resolvedAddress, tcpConfig, true, executionContext,
(channel, connectionObserver) -> H2ClientParentConnectionContext.initChannel(channel,
executionContext, config.h2Config(), reqRespFactoryFunc.apply(HTTP_2_0),
tcpConfig.flushStrategy(), tcpConfig.idleTimeoutMs(),
tcpConfig.flushStrategy(), tcpConfig.idleTimeoutMs(), tcpConfig.sslConfig(),
new TcpClientChannelInitializer(tcpConfig, connectionObserver).andThen(
new H2ClientParentChannelInitializer(config.h2Config())), connectionObserver,
config.allowDropTrailersReadFromTransport()), observer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.servicetalk.http.api.HttpExecutionContext;
import io.servicetalk.http.api.HttpProtocolVersion;
import io.servicetalk.transport.api.ConnectionObserver;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.FlushStrategy;
import io.servicetalk.transport.netty.internal.FlushStrategyHolder;
import io.servicetalk.transport.netty.internal.NettyChannelListenableAsyncCloseable;
Expand Down Expand Up @@ -69,18 +70,22 @@ class H2ParentConnectionContext extends NettyChannelListenableAsyncCloseable imp
private final Processor onClosing = newCompletableProcessor();
private final KeepAliveManager keepAliveManager;
@Nullable
private final SslConfig sslConfig;
@Nullable
final Long idleTimeoutMs;
@Nullable
private SSLSession sslSession;

H2ParentConnectionContext(final Channel channel, final HttpExecutionContext executionContext,
final FlushStrategy flushStrategy, @Nullable final Long idleTimeoutMs,
@Nullable final SslConfig sslConfig,
final KeepAliveManager keepAliveManager) {
super(channel, executionContext.executor());
this.executionContext = new DefaultHttpExecutionContext(executionContext.bufferAllocator(),
fromNettyEventLoop(channel.eventLoop(), executionContext.ioExecutor().isIoThreadSupported()),
executionContext.executor(), executionContext.executionStrategy());
this.flushStrategyHolder = new FlushStrategyHolder(flushStrategy);
this.sslConfig = sslConfig;
this.idleTimeoutMs = idleTimeoutMs;
this.keepAliveManager = keepAliveManager;
// Just in case the channel abruptly closes, we should complete the onClosing Completable.
Expand Down Expand Up @@ -117,6 +122,12 @@ public final SocketAddress remoteAddress() {
return channel().remoteAddress();
}

@Nullable
@Override
public SslConfig sslConfig() {
return sslConfig;
}

@Nullable
@Override
public final SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.servicetalk.transport.api.ConnectionObserver.MultiplexedObserver;
import io.servicetalk.transport.api.ConnectionObserver.StreamObserver;
import io.servicetalk.transport.api.ServerContext;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.ChannelCloseUtils;
import io.servicetalk.transport.netty.internal.ChannelInitializer;
import io.servicetalk.transport.netty.internal.CloseHandler;
Expand Down Expand Up @@ -64,9 +65,10 @@ final class H2ServerParentConnectionContext extends H2ParentConnectionContext im
private H2ServerParentConnectionContext(final Channel channel, final HttpExecutionContext executionContext,
final FlushStrategy flushStrategy,
@Nullable final Long idleTimeoutMs,
@Nullable final SslConfig sslConfig,
final SocketAddress listenAddress,
final KeepAliveManager keepAliveManager) {
super(channel, executionContext, flushStrategy, idleTimeoutMs, keepAliveManager);
super(channel, executionContext, flushStrategy, idleTimeoutMs, sslConfig, keepAliveManager);
this.listenAddress = requireNonNull(listenAddress);
}

Expand Down Expand Up @@ -129,7 +131,7 @@ protected void handleSubscribe(final Subscriber<? super H2ServerParentConnection
final FlushStrategy parentFlushStrategy = config.tcpConfig().flushStrategy();
H2ServerParentConnectionContext connection = new H2ServerParentConnectionContext(channel,
httpExecutionContext, parentFlushStrategy, config.tcpConfig().idleTimeoutMs(),
listenAddress, keepAliveManager);
config.tcpConfig().sslConfig(), listenAddress, keepAliveManager);
channel.attr(CHANNEL_CLOSEABLE_KEY).set(connection);
// We need the NettyToStChannelInboundHandler to be last in the pipeline. We accomplish that by
// calling the ChannelInitializer before we do addLast for the NettyToStChannelInboundHandler.
Expand Down Expand Up @@ -171,6 +173,7 @@ protected void initChannel(final Http2StreamChannel streamChannel) {
connection.flushStrategyHolder.currentStrategy(),
connection.idleTimeoutMs,
HTTP_2_0,
connection.sslConfig(),
connection.sslSession(),
channel.config(),
streamObserver,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.servicetalk.tcp.netty.internal.TcpServerChannelInitializer;
import io.servicetalk.transport.api.ConnectionObserver;
import io.servicetalk.transport.api.ServerContext;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.ChannelInitializer;
import io.servicetalk.transport.netty.internal.CloseHandler;
import io.servicetalk.transport.netty.internal.CloseHandler.CloseEventObservedException;
Expand Down Expand Up @@ -169,10 +170,11 @@ private static Single<NettyHttpServerConnection> initChannel(final Channel chann
if (h1Config == null) {
return failed(newH1ConfigException());
}
final ReadOnlyTcpServerConfig tcpConfig = config.tcpConfig();
return showPipeline(DefaultNettyConnection.initChannel(channel,
httpExecutionContext.bufferAllocator(), httpExecutionContext.executor(),
httpExecutionContext.ioExecutor(), closeHandler, config.tcpConfig().flushStrategy(),
config.tcpConfig().idleTimeoutMs(),
httpExecutionContext.ioExecutor(), closeHandler, tcpConfig.flushStrategy(), tcpConfig.idleTimeoutMs(),
tcpConfig.sslConfig(),
initializer.andThen(getChannelInitializer(getByteBufAllocator(httpExecutionContext.bufferAllocator()),
h1Config, closeHandler)), httpExecutionContext.executionStrategy(), HTTP_1_1, observer, false,
__ -> false)
Expand Down Expand Up @@ -480,6 +482,12 @@ public SocketAddress remoteAddress() {
return connection.remoteAddress();
}

@Nullable
@Override
public SslConfig sslConfig() {
return connection.sslConfig();
}

@Nullable
@Override
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.concurrent.internal.ConcurrentUtils;
import io.servicetalk.transport.api.ExecutionContext;
import io.servicetalk.transport.api.SslConfig;
import io.servicetalk.transport.netty.internal.FlushStrategy;
import io.servicetalk.transport.netty.internal.NettyConnection;
import io.servicetalk.transport.netty.internal.NettyConnectionContext;
Expand Down Expand Up @@ -137,6 +138,12 @@ public SocketAddress remoteAddress() {
return connection.remoteAddress();
}

@Nullable
@Override
public SslConfig sslConfig() {
return connection.sslConfig();
}

@Override
@Nullable
public SSLSession sslSession() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static Single<? extends DefaultNettyConnection<Object, Object>> createConnection
final CloseHandler closeHandler = forPipelinedRequestResponse(true, channel.config());
return showPipeline(DefaultNettyConnection.initChannel(channel, executionContext.bufferAllocator(),
executionContext.executor(), executionContext.ioExecutor(), closeHandler,
tcpConfig.flushStrategy(), tcpConfig.idleTimeoutMs(),
tcpConfig.flushStrategy(), tcpConfig.idleTimeoutMs(), tcpConfig.sslConfig(),
initializer.andThen(new HttpClientChannelInitializer(
getByteBufAllocator(executionContext.bufferAllocator()), h1Config, closeHandler)),
executionContext.executionStrategy(), HTTP_1_1, connectionObserver, true, OBJ_EXPECT_CONTINUE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ void testAlpnConnection(List<String> serverSideProtocols,

try (ReservedBlockingHttpConnection connection = client.reserveConnection(client.get("/"))) {
assertThat(connection.connectionContext().protocol(), is(expectedProtocol));
assertThat(connection.connectionContext().sslConfig(), is(notNullValue()));
assertThat(connection.connectionContext().sslSession(), is(notNullValue()));

assertResponseAndServiceContext(connection.request(client.get("/")));
Expand Down Expand Up @@ -212,6 +213,7 @@ private void assertResponseAndServiceContext(HttpResponse response) throws Excep
HttpServiceContext serviceCtx = serviceContext.take();
assertThat(serviceCtx.protocol(), is(expectedProtocol));
assertThat(serviceCtx.sslSession(), is(notNullValue()));
assertThat(serviceCtx.sslSession(), is(notNullValue()));
assertThat(requestVersion.take(), is(expectedProtocol));

assertThat(serviceContext, is(empty()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ void protocolPayloadEndOutboundShouldNotTriggerOnFailedFlush() throws Exception
(channel, observer) -> DefaultNettyConnection.initChannel(channel, SEC.bufferAllocator(),
SEC.executor(), SEC.ioExecutor(),
forPipelinedRequestResponse(false, channel.config()), defaultFlushStrategy(), null,
null,
new TcpServerChannelInitializer(sConfig, observer).andThen(
channel2 -> {
serverChannelRef.compareAndSet(null, channel2);
Expand All @@ -439,8 +440,9 @@ void protocolPayloadEndOutboundShouldNotTriggerOnFailedFlush() throws Exception
closeHandlerRef.compareAndSet(null, closeHandler);
return DefaultNettyConnection.initChannel(channel, CEC.bufferAllocator(),
CEC.executor(), CEC.ioExecutor(),
closeHandler, defaultFlushStrategy(),
null, new TcpClientChannelInitializer(cConfig.tcpConfig(),
closeHandler, defaultFlushStrategy(), null,
cConfig.tcpConfig().sslConfig(),
new TcpClientChannelInitializer(cConfig.tcpConfig(),
connectionObserver)
.andThen(new HttpClientChannelInitializer(
getByteBufAllocator(CEC.bufferAllocator()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void setUp() throws Exception {
CloseHandler closeHandler = UNSUPPORTED_PROTOCOL_CLOSE_HANDLER;
final DefaultNettyConnection<Integer, Integer> connection =
DefaultNettyConnection.<Integer, Integer>initChannel(channel, DEFAULT_ALLOCATOR,
immediate(), null, closeHandler, defaultFlushStrategy(), null, channel2 -> {
immediate(), null, closeHandler, defaultFlushStrategy(), null, null, channel2 -> {
channel2.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Expand Down
Loading

0 comments on commit b802c8c

Please sign in to comment.