Skip to content

Commit

Permalink
Immutable local/remote SocketAddress within a ConnectionMetaData (#10867
Browse files Browse the repository at this point in the history
)

The local/remote SocketAddress is cached within the ConnectionMetaData or Connection instance, so that any changes are not visible during the request lifetime.
Ensure that all server Connection types respect HttpConfiguration#getLocalAddress and that it is not implemented only in servlet layer
Avoid DNS resolution.

---------

Co-authored-by: Joakim Erdfelt <[email protected]>
  • Loading branch information
gregw and joakime authored Nov 13, 2023
1 parent fb84f3f commit 2c35f5a
Show file tree
Hide file tree
Showing 12 changed files with 459 additions and 434 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

package org.eclipse.jetty.fcgi.server.internal;

import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.Set;
import java.util.concurrent.TimeoutException;
Expand All @@ -25,12 +24,11 @@
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.RetainableByteBuffer;
import org.eclipse.jetty.server.AbstractMetaDataConnection;
import org.eclipse.jetty.server.ConnectionMetaData;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpChannel;
Expand All @@ -40,7 +38,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServerFCGIConnection extends AbstractConnection implements ConnectionMetaData
public class ServerFCGIConnection extends AbstractMetaDataConnection implements ConnectionMetaData
{
private static final Logger LOG = LoggerFactory.getLogger(ServerFCGIConnection.class);

Expand All @@ -60,7 +58,7 @@ public class ServerFCGIConnection extends AbstractConnection implements Connecti

public ServerFCGIConnection(Connector connector, EndPoint endPoint, HttpConfiguration configuration, boolean sendStatus200)
{
super(endPoint, connector.getExecutor());
super(connector, configuration, endPoint);
this.connector = connector;
this.networkByteBufferPool = connector.getByteBufferPool();
this.flusher = new Flusher(endPoint);
Expand Down Expand Up @@ -106,12 +104,6 @@ public String getId()
return id;
}

@Override
public HttpConfiguration getHttpConfiguration()
{
return configuration;
}

@Override
public HttpVersion getHttpVersion()
{
Expand All @@ -124,18 +116,6 @@ public String getProtocol()
return "fcgi/1.0";
}

@Override
public Connection getConnection()
{
return this;
}

@Override
public Connector getConnector()
{
return connector;
}

@Override
public boolean isPersistent()
{
Expand All @@ -148,18 +128,6 @@ public boolean isSecure()
return false;
}

@Override
public SocketAddress getRemoteSocketAddress()
{
return getEndPoint().getRemoteSocketAddress();
}

@Override
public SocketAddress getLocalSocketAddress()
{
return getEndPoint().getLocalSocketAddress();
}

@Override
public Object removeAttribute(String name)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
private final ServerSessionListener listener;
private final HttpConfiguration httpConfig;
private final String id;
private final SocketAddress localSocketAddress;
private final SocketAddress remoteSocketAddress;

public HTTP2ServerConnection(Connector connector, EndPoint endPoint, HttpConfiguration httpConfig, HTTP2ServerSession session, int inputBufferSize, ServerSessionListener listener)
{
Expand All @@ -74,6 +76,8 @@ public HTTP2ServerConnection(Connector connector, EndPoint endPoint, HttpConfigu
this.listener = listener;
this.httpConfig = httpConfig;
this.id = StringUtil.randomAlphaNumeric(16);
localSocketAddress = httpConfig.getLocalAddress() != null ? httpConfig.getLocalAddress() : endPoint.getLocalSocketAddress();
remoteSocketAddress = endPoint.getRemoteSocketAddress();
}

@Override
Expand Down Expand Up @@ -400,13 +404,13 @@ public boolean isPushSupported()
@Override
public SocketAddress getRemoteSocketAddress()
{
return getEndPoint().getRemoteSocketAddress();
return remoteSocketAddress;
}

@Override
public SocketAddress getLocalSocketAddress()
{
return getEndPoint().getLocalSocketAddress();
return localSocketAddress;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.HostPort;

public class ServerHTTP3StreamConnection extends HTTP3StreamConnection implements ConnectionMetaData
public class ServerHTTP3StreamConnection extends HTTP3StreamConnection
{
private final HttpChannel.Factory httpChannelFactory = new HttpChannel.DefaultFactory();
private final Attributes attributes = new Attributes.Lazy();
Expand All @@ -51,7 +51,8 @@ public ServerHTTP3StreamConnection(Connector connector, HttpConfiguration httpCo

public Runnable onRequest(HTTP3StreamServer stream, HeadersFrame frame)
{
HttpChannel httpChannel = httpChannelFactory.newHttpChannel(this);
// Create new metadata for every request as the local or remote address may have changed.
HttpChannel httpChannel = httpChannelFactory.newHttpChannel(new MetaData());
HttpStreamOverHTTP3 httpStream = new HttpStreamOverHTTP3(this, httpChannel, stream);
httpChannel.setHttpStream(httpStream);
stream.setAttachment(httpStream);
Expand Down Expand Up @@ -87,107 +88,119 @@ void offer(Runnable task)
session.offer(task, false);
}

@Override
public String getId()
{
return session.getQuicSession().getConnectionId().toString();
}

@Override
public HttpConfiguration getHttpConfiguration()
{
return httpConfiguration;
}

@Override
public HttpVersion getHttpVersion()
{
return HttpVersion.HTTP_3;
}

@Override
public String getProtocol()
{
return getHttpVersion().asString();
}

@Override
public Connection getConnection()
{
return getEndPoint().getConnection();
}

@Override
public Connector getConnector()
{
return connector;
}

@Override
public boolean isPersistent()
{
return true;
}

@Override
public boolean isSecure()
{
return true;
}

@Override
public SocketAddress getRemoteSocketAddress()
{
return getEndPoint().getRemoteSocketAddress();
}

@Override
public SocketAddress getLocalSocketAddress()
{
return getEndPoint().getLocalSocketAddress();
}

@Override
public HostPort getServerAuthority()
{
HostPort override = httpConfiguration.getServerAuthority();
if (override != null)
return override;

// TODO cache the HostPort?
SocketAddress addr = getLocalSocketAddress();
if (addr instanceof InetSocketAddress inet)
return new HostPort(inet.getHostString(), inet.getPort());
return new HostPort(addr.toString(), -1);
}

@Override
public Object getAttribute(String name)
{
return attributes.getAttribute(name);
}

@Override
public Object setAttribute(String name, Object attribute)
{
return attributes.setAttribute(name, attribute);
}

@Override
public Object removeAttribute(String name)
{
return attributes.removeAttribute(name);
}

@Override
public Set<String> getAttributeNameSet()
{
return attributes.getAttributeNameSet();
}

@Override
public void clearAttributes()
{
attributes.clearAttributes();
private class MetaData implements ConnectionMetaData
{
private final SocketAddress localSocketAddress;
private final SocketAddress remoteSocketAddress;

private MetaData()
{
this.localSocketAddress = httpConfiguration.getLocalAddress() == null ? getEndPoint().getLocalSocketAddress() : httpConfiguration.getLocalAddress();
this.remoteSocketAddress = getEndPoint().getRemoteSocketAddress();
}

@Override
public String getId()
{
return session.getQuicSession().getConnectionId().toString();
}

@Override
public HttpConfiguration getHttpConfiguration()
{
return httpConfiguration;
}

@Override
public HttpVersion getHttpVersion()
{
return HttpVersion.HTTP_3;
}

@Override
public String getProtocol()
{
return getHttpVersion().asString();
}

@Override
public Connection getConnection()
{
return getEndPoint().getConnection();
}

@Override
public Connector getConnector()
{
return connector;
}

@Override
public boolean isPersistent()
{
return true;
}

@Override
public boolean isSecure()
{
return true;
}

@Override
public SocketAddress getRemoteSocketAddress()
{
return remoteSocketAddress;
}

@Override
public SocketAddress getLocalSocketAddress()
{
return localSocketAddress;
}

@Override
public HostPort getServerAuthority()
{
HostPort override = httpConfiguration.getServerAuthority();
if (override != null)
return override;

// TODO cache the HostPort?
SocketAddress addr = getLocalSocketAddress();
if (addr instanceof InetSocketAddress inet)
return new HostPort(inet.getHostString(), inet.getPort());
return new HostPort(addr.toString(), -1);
}

@Override
public Object getAttribute(String name)
{
return attributes.getAttribute(name);
}

@Override
public Object setAttribute(String name, Object attribute)
{
return attributes.setAttribute(name, attribute);
}

@Override
public Object removeAttribute(String name)
{
return attributes.removeAttribute(name);
}

@Override
public Set<String> getAttributeNameSet()
{
return attributes.getAttributeNameSet();
}

@Override
public void clearAttributes()
{
attributes.clearAttributes();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ public InetSocketAddress getLocalAddress()
}

@Override
public SocketAddress getLocalSocketAddress()
{
return null;
}
public abstract SocketAddress getLocalSocketAddress();

@Override
public InetSocketAddress getRemoteAddress()
Expand All @@ -84,10 +81,7 @@ public InetSocketAddress getRemoteAddress()
}

@Override
public SocketAddress getRemoteSocketAddress()
{
return null;
}
public abstract SocketAddress getRemoteSocketAddress();

protected final void shutdownInput()
{
Expand Down
Loading

0 comments on commit 2c35f5a

Please sign in to comment.