Class BinaryRelay

java.lang.Object
org.mockserver.netty.proxy.relay.BinaryRelay

public final class BinaryRelay extends Object
One binary client connection's single upstream connection, and the bytes relayed between the two as they arrive. Kept in a channel attribute of the client connection. The upstream connection is registered on the client connection's event loop, so everything here runs on that one thread; only the listener runs elsewhere.

Neither connection is read while the other cannot take what is read from it, so what is held is one read each way, each connection's write buffer and the messages not yet reported to the listener.

When the client turns TLS on part way through (PostgreSQL's SSLRequest), MockServer answers the client's handshake as it does for any TLS connection and starts its own handshake with the upstream on the same upstream connection, so what was sent before goes up in the clear and everything after over TLS. A client whose connection was TLS from its first byte gets an upstream connection that is TLS from its first byte too.

The upstream connection is made directly or through a tunnel: SOCKS5 for forwardSocksProxy, CONNECT for forwardHttpsProxy or forwardHttpProxy.

  • Method Summary

    Modifier and Type
    Method
    Description
    static void
    answeredLocally(io.netty.channel.Channel client, String logCorrelationId)
    Called once MockServer has written its own reply to a message read from the client, which is not relayed and is not reported to the listener.
    static void
    clientInactive(io.netty.channel.Channel client)
    Ends the upstream connection once the client's has closed, after what the client sent has been written to it.
    static void
    clientStartedTls(io.netty.channel.Channel client)
    The client has started TLS part way through: its handshake with MockServer is under way, so the upstream connection starts its own.
    static void
    clientWritabilityChanged(io.netty.channel.Channel client)
    Reads the upstream again once the client can take more.
    static void
    forward(io.netty.channel.ChannelHandlerContext ctx, org.mockserver.model.BinaryMessage binaryRequest, String logCorrelationId, UpstreamReply reply, InetSocketAddress target, org.mockserver.configuration.Configuration configuration, org.mockserver.logging.MockServerLogger mockServerLogger, org.mockserver.scheduler.Scheduler scheduler, org.mockserver.httpclient.NettyHttpClient httpClient, org.mockserver.model.BinaryProxyListener listener)
    Relays a message read from the client to its upstream connection, opening that connection for the first one, with the upstream's reply to this message relayed, dropped or replaced.
    static boolean
    hasRelay(io.netty.channel.Channel client)
    Whether this connection has a relay, which then holds the client back itself when MockServer's own reply leaves it not writable (answeredLocally(io.netty.channel.Channel, java.lang.String)).
    static void
    openBeforeClientSpeaks(io.netty.channel.ChannelHandlerContext ctx, InetSocketAddress target, org.mockserver.configuration.Configuration configuration, org.mockserver.logging.MockServerLogger mockServerLogger, org.mockserver.scheduler.Scheduler scheduler, org.mockserver.httpclient.NettyHttpClient httpClient, org.mockserver.model.BinaryProxyListener listener)
    Opens the upstream connection of a client that has sent nothing yet, so that a server that speaks first (forwardBinaryServerFirstWaitMillis) is heard: what it sends is relayed to the client as any upstream read is.
    static void
    prepare(io.netty.channel.ChannelHandlerContext ctx, InetSocketAddress target, org.mockserver.configuration.Configuration configuration, org.mockserver.logging.MockServerLogger mockServerLogger, org.mockserver.scheduler.Scheduler scheduler, org.mockserver.httpclient.NettyHttpClient httpClient, org.mockserver.model.BinaryProxyListener listener)
    Makes this connection's relay, if it has none yet, without opening its upstream connection, so that a message MockServer answers itself (matchBinaryExpectationsWhenProxying) is ordered and held back by it.
    static boolean
    tracksReplies(io.netty.channel.Channel client)
    Whether this connection's relay knows where the upstream's reply to each message ends, so a reply can be dropped or replaced: one relayed with a protocol's framing (binaryMessageFraming POSTGRESQL) whose tracking has not been given up on a malformed upstream message.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • forward

      public static void forward(io.netty.channel.ChannelHandlerContext ctx, org.mockserver.model.BinaryMessage binaryRequest, String logCorrelationId, UpstreamReply reply, InetSocketAddress target, org.mockserver.configuration.Configuration configuration, org.mockserver.logging.MockServerLogger mockServerLogger, org.mockserver.scheduler.Scheduler scheduler, org.mockserver.httpclient.NettyHttpClient httpClient, org.mockserver.model.BinaryProxyListener listener)
      Relays a message read from the client to its upstream connection, opening that connection for the first one, with the upstream's reply to this message relayed, dropped or replaced. A reply is dropped or replaced only on a connection whose replies are tracked (tracksReplies(Channel)); on any other it is relayed. Must be called on the client connection's event loop.
    • hasRelay

      public static boolean hasRelay(io.netty.channel.Channel client)
      Whether this connection has a relay, which then holds the client back itself when MockServer's own reply leaves it not writable (answeredLocally(io.netty.channel.Channel, java.lang.String)).
    • tracksReplies

      public static boolean tracksReplies(io.netty.channel.Channel client)
      Whether this connection's relay knows where the upstream's reply to each message ends, so a reply can be dropped or replaced: one relayed with a protocol's framing (binaryMessageFraming POSTGRESQL) whose tracking has not been given up on a malformed upstream message. Must be called on the client connection's event loop.
    • prepare

      public static void prepare(io.netty.channel.ChannelHandlerContext ctx, InetSocketAddress target, org.mockserver.configuration.Configuration configuration, org.mockserver.logging.MockServerLogger mockServerLogger, org.mockserver.scheduler.Scheduler scheduler, org.mockserver.httpclient.NettyHttpClient httpClient, org.mockserver.model.BinaryProxyListener listener)
      Makes this connection's relay, if it has none yet, without opening its upstream connection, so that a message MockServer answers itself (matchBinaryExpectationsWhenProxying) is ordered and held back by it. Must be called on the client connection's event loop.
    • openBeforeClientSpeaks

      public static void openBeforeClientSpeaks(io.netty.channel.ChannelHandlerContext ctx, InetSocketAddress target, org.mockserver.configuration.Configuration configuration, org.mockserver.logging.MockServerLogger mockServerLogger, org.mockserver.scheduler.Scheduler scheduler, org.mockserver.httpclient.NettyHttpClient httpClient, org.mockserver.model.BinaryProxyListener listener)
      Opens the upstream connection of a client that has sent nothing yet, so that a server that speaks first (forwardBinaryServerFirstWaitMillis) is heard: what it sends is relayed to the client as any upstream read is. Must be called on the client connection's event loop.
    • answeredLocally

      public static void answeredLocally(io.netty.channel.Channel client, String logCorrelationId)
      Called once MockServer has written its own reply to a message read from the client, which is not relayed and is not reported to the listener. Nothing orders that reply against what the upstream still owes an earlier message, so that case is logged; and the client is not read while it cannot take more.
    • clientInactive

      public static void clientInactive(io.netty.channel.Channel client)
      Ends the upstream connection once the client's has closed, after what the client sent has been written to it. Called from the client connection's channelInactive, not its close future, which completes before the handlers in front of this one hand over the bytes they still hold (a possible handshake start, a gathered message). A connection without a relay is left alone.
    • clientStartedTls

      public static void clientStartedTls(io.netty.channel.Channel client)
      The client has started TLS part way through: its handshake with MockServer is under way, so the upstream connection starts its own. Called when the client's server certificate has been chosen (Netty's SniCompletionEvent), before anything the client sends over TLS is decrypted. A connection without a relay is left alone.
    • clientWritabilityChanged

      public static void clientWritabilityChanged(io.netty.channel.Channel client)
      Reads the upstream again once the client can take more. A connection without a relay is left alone.