Issue #132 - ClientConnector abstraction.
Rewrote HttpClientTransportOverUnixSockets in light of ClientConnector. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
64a2bc346e
commit
51730a7ccf
|
@ -18,12 +18,14 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.client;
|
package org.eclipse.jetty.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.api.Connection;
|
import org.eclipse.jetty.client.api.Connection;
|
||||||
import org.eclipse.jetty.io.ClientConnector;
|
import org.eclipse.jetty.io.ClientConnector;
|
||||||
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.util.Promise;
|
import org.eclipse.jetty.util.Promise;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
|
@ -75,4 +77,18 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC
|
||||||
context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, new Promise.Wrapper<>(promise));
|
context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, new Promise.Wrapper<>(promise));
|
||||||
connector.connect(address, context);
|
connector.connect(address, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
|
||||||
|
{
|
||||||
|
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Promise<Connection> promise = (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
||||||
|
org.eclipse.jetty.io.Connection connection = newHttpConnection(endPoint, destination, promise);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Created {}", connection);
|
||||||
|
return customize(connection, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract org.eclipse.jetty.io.Connection newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.client.http;
|
package org.eclipse.jetty.client.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||||
import org.eclipse.jetty.client.DuplexConnectionPool;
|
import org.eclipse.jetty.client.DuplexConnectionPool;
|
||||||
import org.eclipse.jetty.client.HttpDestination;
|
import org.eclipse.jetty.client.HttpDestination;
|
||||||
|
@ -58,18 +55,6 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran
|
||||||
return new HttpDestinationOverHTTP(getHttpClient(), origin);
|
return new HttpDestinationOverHTTP(getHttpClient(), origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context) throws IOException
|
|
||||||
{
|
|
||||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Promise<Connection> promise = (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
|
||||||
HttpConnectionOverHTTP connection = newHttpConnection(endPoint, destination, promise);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Created {}", connection);
|
|
||||||
return customize(connection, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
||||||
{
|
{
|
||||||
return new HttpConnectionOverHTTP(endPoint, destination, promise);
|
return new HttpConnectionOverHTTP(endPoint, destination, promise);
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.fcgi.client.http;
|
package org.eclipse.jetty.fcgi.client.http;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||||
import org.eclipse.jetty.client.DuplexConnectionPool;
|
import org.eclipse.jetty.client.DuplexConnectionPool;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
@ -76,18 +74,6 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran
|
||||||
return new HttpDestinationOverFCGI(getHttpClient(), origin);
|
return new HttpDestinationOverFCGI(getHttpClient(), origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public org.eclipse.jetty.io.Connection newConnection(EndPoint endPoint, Map<String, Object> context)
|
|
||||||
{
|
|
||||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Promise<Connection> promise = (Promise<Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
|
||||||
HttpConnectionOverFCGI connection = newHttpConnection(endPoint, destination, promise);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Created {}", connection);
|
|
||||||
return customize(connection, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpConnectionOverFCGI newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
protected HttpConnectionOverFCGI newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<Connection> promise)
|
||||||
{
|
{
|
||||||
return new HttpConnectionOverFCGI(endPoint, destination, promise);
|
return new HttpConnectionOverFCGI(endPoint, destination, promise);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.io;
|
package org.eclipse.jetty.io;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
@ -251,20 +252,8 @@ public class ClientConnector extends ContainerLifeCycle
|
||||||
// exception is being thrown, so we attempt to provide a better error message.
|
// exception is being thrown, so we attempt to provide a better error message.
|
||||||
if (x.getClass() == SocketException.class)
|
if (x.getClass() == SocketException.class)
|
||||||
x = new SocketException("Could not connect to " + address).initCause(x);
|
x = new SocketException("Could not connect to " + address).initCause(x);
|
||||||
|
safeClose(channel);
|
||||||
try
|
connectFailed(x, context);
|
||||||
{
|
|
||||||
if (channel != null)
|
|
||||||
channel.close();
|
|
||||||
}
|
|
||||||
catch (IOException xx)
|
|
||||||
{
|
|
||||||
LOG.ignore(xx);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
connectFailed(x, context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +262,6 @@ public class ClientConnector extends ContainerLifeCycle
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
context.put(ClientConnector.CLIENT_CONNECTOR_CONTEXT_KEY, this);
|
context.put(ClientConnector.CLIENT_CONNECTOR_CONTEXT_KEY, this);
|
||||||
|
|
||||||
if (!channel.isConnected())
|
if (!channel.isConnected())
|
||||||
throw new IllegalStateException("SocketChannel must be connected");
|
throw new IllegalStateException("SocketChannel must be connected");
|
||||||
configure(channel);
|
configure(channel);
|
||||||
|
@ -284,17 +272,31 @@ public class ClientConnector extends ContainerLifeCycle
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Could not accept {}", channel);
|
LOG.debug("Could not accept {}", channel);
|
||||||
|
safeClose(channel);
|
||||||
Promise<?> promise = (Promise<?>)context.get(CONNECTION_PROMISE_CONTEXT_KEY);
|
Promise<?> promise = (Promise<?>)context.get(CONNECTION_PROMISE_CONTEXT_KEY);
|
||||||
promise.failed(failure);
|
promise.failed(failure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void safeClose(Closeable closeable)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (closeable != null)
|
||||||
|
closeable.close();
|
||||||
|
}
|
||||||
|
catch (Throwable x)
|
||||||
|
{
|
||||||
|
LOG.ignore(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void configure(SocketChannel channel) throws IOException
|
protected void configure(SocketChannel channel) throws IOException
|
||||||
{
|
{
|
||||||
channel.socket().setTcpNoDelay(true);
|
channel.socket().setTcpNoDelay(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connectFailed(Throwable failure, Map<String, Object> context)
|
protected void connectFailed(Throwable failure, Map<String, Object> context)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("Could not connect to {}", context.get(SOCKET_ADDRESS_CONTEXT_KEY));
|
LOG.debug("Could not connect to {}", context.get(SOCKET_ADDRESS_CONTEXT_KEY));
|
||||||
|
@ -302,9 +304,9 @@ public class ClientConnector extends ContainerLifeCycle
|
||||||
promise.failed(failure);
|
promise.failed(failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ClientSelectorManager extends SelectorManager
|
protected class ClientSelectorManager extends SelectorManager
|
||||||
{
|
{
|
||||||
private ClientSelectorManager(Executor executor, Scheduler scheduler, int selectors)
|
protected ClientSelectorManager(Executor executor, Scheduler scheduler, int selectors)
|
||||||
{
|
{
|
||||||
super(executor, scheduler, selectors);
|
super(executor, scheduler, selectors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,31 +20,25 @@ package org.eclipse.jetty.unixsocket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
|
|
||||||
|
import jnr.unixsocket.UnixSocketChannel;
|
||||||
import org.eclipse.jetty.io.ChannelEndPoint;
|
import org.eclipse.jetty.io.ChannelEndPoint;
|
||||||
import org.eclipse.jetty.io.EofException;
|
|
||||||
import org.eclipse.jetty.io.ManagedSelector;
|
import org.eclipse.jetty.io.ManagedSelector;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
import jnr.unixsocket.UnixSocketChannel;
|
|
||||||
|
|
||||||
public class UnixSocketEndPoint extends ChannelEndPoint
|
public class UnixSocketEndPoint extends ChannelEndPoint
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(UnixSocketEndPoint.class);
|
private static final Logger LOG = Log.getLogger(UnixSocketEndPoint.class);
|
||||||
private static final Logger CEPLOG = Log.getLogger(ChannelEndPoint.class);
|
|
||||||
|
|
||||||
|
|
||||||
private final UnixSocketChannel _channel;
|
private final UnixSocketChannel _channel;
|
||||||
|
|
||||||
public UnixSocketEndPoint(UnixSocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
public UnixSocketEndPoint(UnixSocketChannel channel, ManagedSelector selector, SelectionKey key, Scheduler scheduler)
|
||||||
{
|
{
|
||||||
super(channel,selector,key,scheduler);
|
super(channel, selector, key, scheduler);
|
||||||
_channel=channel;
|
_channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,7 +53,6 @@ public class UnixSocketEndPoint extends ChannelEndPoint
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doShutdownOutput()
|
protected void doShutdownOutput()
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,25 +19,28 @@
|
||||||
package org.eclipse.jetty.unixsocket.client;
|
package org.eclipse.jetty.unixsocket.client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.ConnectException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.nio.channels.SelectableChannel;
|
import java.nio.channels.SelectableChannel;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.Selector;
|
import java.nio.channels.Selector;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import jnr.enxio.channels.NativeSelectorProvider;
|
import jnr.enxio.channels.NativeSelectorProvider;
|
||||||
import jnr.unixsocket.UnixSocketAddress;
|
import jnr.unixsocket.UnixSocketAddress;
|
||||||
import jnr.unixsocket.UnixSocketChannel;
|
import jnr.unixsocket.UnixSocketChannel;
|
||||||
import org.eclipse.jetty.client.AbstractHttpClientTransport;
|
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||||
import org.eclipse.jetty.client.DuplexConnectionPool;
|
import org.eclipse.jetty.client.DuplexConnectionPool;
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
import org.eclipse.jetty.client.HttpDestination;
|
import org.eclipse.jetty.client.HttpDestination;
|
||||||
import org.eclipse.jetty.client.Origin;
|
import org.eclipse.jetty.client.Origin;
|
||||||
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
|
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
|
||||||
import org.eclipse.jetty.client.http.HttpDestinationOverHTTP;
|
import org.eclipse.jetty.client.http.HttpDestinationOverHTTP;
|
||||||
import org.eclipse.jetty.io.Connection;
|
import org.eclipse.jetty.io.ClientConnector;
|
||||||
import org.eclipse.jetty.io.EndPoint;
|
import org.eclipse.jetty.io.EndPoint;
|
||||||
import org.eclipse.jetty.io.ManagedSelector;
|
import org.eclipse.jetty.io.ManagedSelector;
|
||||||
import org.eclipse.jetty.io.SelectorManager;
|
import org.eclipse.jetty.io.SelectorManager;
|
||||||
|
@ -45,22 +48,21 @@ import org.eclipse.jetty.unixsocket.UnixSocketEndPoint;
|
||||||
import org.eclipse.jetty.util.Promise;
|
import org.eclipse.jetty.util.Promise;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
// TODO: this class needs a thorough review.
|
// TODO: this class needs a thorough review.
|
||||||
public class HttpClientTransportOverUnixSockets extends AbstractHttpClientTransport
|
public class HttpClientTransportOverUnixSockets extends AbstractConnectorHttpClientTransport
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(HttpClientTransportOverUnixSockets.class);
|
private static final Logger LOG = Log.getLogger(HttpClientTransportOverUnixSockets.class);
|
||||||
|
|
||||||
private String _unixSocket;
|
|
||||||
private SelectorManager selectorManager;
|
|
||||||
|
|
||||||
private UnixSocketChannel channel;
|
|
||||||
|
|
||||||
public HttpClientTransportOverUnixSockets(String unixSocket)
|
public HttpClientTransportOverUnixSockets(String unixSocket)
|
||||||
{
|
{
|
||||||
if (unixSocket == null)
|
this(new UnixSocketClientConnector(unixSocket));
|
||||||
throw new IllegalArgumentException("Unix socket file cannot be null");
|
}
|
||||||
this._unixSocket = unixSocket;
|
|
||||||
|
private HttpClientTransportOverUnixSockets(ClientConnector connector)
|
||||||
|
{
|
||||||
|
super(connector);
|
||||||
setConnectionPoolFactory(destination ->
|
setConnectionPoolFactory(destination ->
|
||||||
{
|
{
|
||||||
HttpClient httpClient = getHttpClient();
|
HttpClient httpClient = getHttpClient();
|
||||||
|
@ -69,136 +71,80 @@ public class HttpClientTransportOverUnixSockets extends AbstractHttpClientTransp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doStart() throws Exception
|
|
||||||
{
|
|
||||||
HttpClient httpClient = getHttpClient();
|
|
||||||
selectorManager = new UnixSocketSelectorManager(httpClient, 1);
|
|
||||||
selectorManager.setConnectTimeout(httpClient.getConnectTimeout());
|
|
||||||
addBean(selectorManager);
|
|
||||||
super.doStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doStop() throws Exception
|
|
||||||
{
|
|
||||||
super.doStop();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (channel != null)
|
|
||||||
channel.close();
|
|
||||||
}
|
|
||||||
catch (IOException xx)
|
|
||||||
{
|
|
||||||
LOG.ignore(xx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpDestination newHttpDestination(Origin origin)
|
public HttpDestination newHttpDestination(Origin origin)
|
||||||
{
|
{
|
||||||
return new HttpDestinationOverHTTP(getHttpClient(), origin);
|
return new HttpDestinationOverHTTP(getHttpClient(), origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connect(InetSocketAddress address, Map<String, Object> context)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
InetAddress inet = address.getAddress();
|
|
||||||
if (!inet.isLoopbackAddress() && !inet.isLinkLocalAddress() && !inet.isSiteLocalAddress())
|
|
||||||
throw new IOException("UnixSocket cannot connect to " + address.getHostString());
|
|
||||||
|
|
||||||
// Open a unix socket
|
|
||||||
UnixSocketAddress unixAddress = new UnixSocketAddress(this._unixSocket);
|
|
||||||
channel = UnixSocketChannel.open(unixAddress);
|
|
||||||
|
|
||||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
|
||||||
HttpClient client = destination.getHttpClient();
|
|
||||||
|
|
||||||
configure(client, channel);
|
|
||||||
|
|
||||||
channel.configureBlocking(false);
|
|
||||||
selectorManager.accept(channel, context);
|
|
||||||
}
|
|
||||||
// Must catch all exceptions, since some like
|
|
||||||
// UnresolvedAddressException are not IOExceptions.
|
|
||||||
catch (Throwable x)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (channel != null)
|
|
||||||
channel.close();
|
|
||||||
}
|
|
||||||
catch (IOException xx)
|
|
||||||
{
|
|
||||||
LOG.ignore(xx);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
connectFailed(context, x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Connection newConnection(EndPoint endPoint, Map<String, Object> context)
|
|
||||||
{
|
|
||||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Promise<org.eclipse.jetty.client.api.Connection> promise = (Promise<org.eclipse.jetty.client.api.Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
|
||||||
HttpConnectionOverHTTP connection = newHttpConnection(endPoint, destination, promise);
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
LOG.debug("Created {}", connection);
|
|
||||||
return customize(connection, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<org.eclipse.jetty.client.api.Connection> promise)
|
protected HttpConnectionOverHTTP newHttpConnection(EndPoint endPoint, HttpDestination destination, Promise<org.eclipse.jetty.client.api.Connection> promise)
|
||||||
{
|
{
|
||||||
return new HttpConnectionOverHTTP(endPoint, destination, promise);
|
return new HttpConnectionOverHTTP(endPoint, destination, promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void configure(HttpClient client, SocketChannel channel) throws IOException
|
private static class UnixSocketClientConnector extends ClientConnector
|
||||||
{
|
{
|
||||||
channel.socket().setTcpNoDelay(client.isTCPNoDelay());
|
private final String unixSocket;
|
||||||
}
|
|
||||||
|
|
||||||
public class UnixSocketSelectorManager extends SelectorManager
|
private UnixSocketClientConnector(String unixSocket)
|
||||||
{
|
|
||||||
protected UnixSocketSelectorManager(HttpClient client, int selectors)
|
|
||||||
{
|
{
|
||||||
super(client.getExecutor(), client.getScheduler(), selectors);
|
this.unixSocket = unixSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Selector newSelector() throws IOException
|
protected SelectorManager newSelectorManager()
|
||||||
{
|
{
|
||||||
return NativeSelectorProvider.getInstance().openSelector();
|
return new UnixSocketSelectorManager(getExecutor(), getScheduler(), getSelectors());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key)
|
public void connect(SocketAddress address, Map<String, Object> context)
|
||||||
{
|
{
|
||||||
UnixSocketEndPoint endPoint = new UnixSocketEndPoint((UnixSocketChannel)channel, selector, key, getScheduler());
|
InetSocketAddress socketAddress = (InetSocketAddress)address;
|
||||||
endPoint.setIdleTimeout(getHttpClient().getIdleTimeout());
|
InetAddress inetAddress = socketAddress.getAddress();
|
||||||
return endPoint;
|
if (inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress() || inetAddress.isSiteLocalAddress())
|
||||||
|
{
|
||||||
|
SocketChannel channel = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UnixSocketAddress unixAddress = new UnixSocketAddress(unixSocket);
|
||||||
|
channel = UnixSocketChannel.open(unixAddress);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Created {} for {}", channel, unixAddress);
|
||||||
|
accept(channel, context);
|
||||||
|
}
|
||||||
|
catch (Throwable x)
|
||||||
|
{
|
||||||
|
safeClose(channel);
|
||||||
|
connectFailed(x, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
connectFailed(new ConnectException("UnixSocket cannot connect to " + socketAddress.getHostString()), context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private class UnixSocketSelectorManager extends ClientSelectorManager
|
||||||
public Connection newConnection(SelectableChannel channel, EndPoint endPoint, Object attachment) throws IOException
|
|
||||||
{
|
{
|
||||||
@SuppressWarnings("unchecked")
|
private UnixSocketSelectorManager(Executor executor, Scheduler scheduler, int selectors)
|
||||||
Map<String, Object> context = (Map<String, Object>)attachment;
|
{
|
||||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
super(executor, scheduler, selectors);
|
||||||
return destination.getClientConnectionFactory().newConnection(endPoint, context);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void connectionFailed(SelectableChannel channel, Throwable x, Object attachment)
|
protected Selector newSelector() throws IOException
|
||||||
{
|
{
|
||||||
@SuppressWarnings("unchecked")
|
return NativeSelectorProvider.getInstance().openSelector();
|
||||||
Map<String, Object> context = (Map<String, Object>)attachment;
|
}
|
||||||
connectFailed(context, x);
|
|
||||||
|
@Override
|
||||||
|
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key)
|
||||||
|
{
|
||||||
|
UnixSocketEndPoint endPoint = new UnixSocketEndPoint((UnixSocketChannel)channel, selector, key, getScheduler());
|
||||||
|
endPoint.setIdleTimeout(getIdleTimeout().toMillis());
|
||||||
|
return endPoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.unixsocket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.ConnectException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -146,7 +147,6 @@ public class UnixSocketTest
|
||||||
httpClient.start();
|
httpClient.start();
|
||||||
|
|
||||||
ExecutionException e = assertThrows(ExecutionException.class, () -> httpClient.newRequest("http://google.com").send());
|
ExecutionException e = assertThrows(ExecutionException.class, () -> httpClient.newRequest("http://google.com").send());
|
||||||
assertThat(e.getCause(), instanceOf(IOException.class));
|
assertThat(e.getCause(), instanceOf(ConnectException.class));
|
||||||
assertThat(e.getCause().getMessage(), containsString("UnixSocket cannot connect to google.com"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue