existings = new ArrayList<>(_factories.values());
+ _factories.clear();
+ addConnectionFactory(factory);
+ for (ConnectionFactory existing : existings)
+ addConnectionFactory(existing);
+ _defaultProtocol = factory.getProtocol();
+ }
+ }
+
public void addIfAbsentConnectionFactory(ConnectionFactory factory)
{
synchronized (_factories)
@@ -460,8 +473,8 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
/* ------------------------------------------------------------ */
/** Set the acceptor thread priority delta.
* This allows the acceptor thread to run at a different priority.
- * Typically this would be used to lower the priority to give preference
- * to handling previously accepted connections rather than accepting
+ * Typically this would be used to lower the priority to give preference
+ * to handling previously accepted connections rather than accepting
* new connections
* @param acceptorPriorityDelta the acceptor priority delta
*/
@@ -532,7 +545,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
String name=thread.getName();
_name=String.format("%s-acceptor-%d@%x-%s",name,_id,hashCode(),AbstractConnector.this.toString());
thread.setName(_name);
-
+
int priority=thread.getPriority();
if (_acceptorPriorityDelta!=0)
thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_acceptorPriorityDelta)));
@@ -574,7 +587,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
stopping.countDown();
}
}
-
+
@Override
public String toString()
{
@@ -583,7 +596,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
return String.format("acceptor-%d@%x", _id, hashCode());
return name;
}
-
+
}
@@ -636,7 +649,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{
return _name;
}
-
+
/* ------------------------------------------------------------ */
/**
* Set a connector name. A context may be configured with
@@ -648,7 +661,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{
_name=name;
}
-
+
@Override
public String toString()
{
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java
index f810f4c55a..b72cf5718d 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java
@@ -35,11 +35,11 @@ import org.eclipse.jetty.util.log.Logger;
/* ------------------------------------------------------------ */
-/**
+/**
* ConnectionFactory for the PROXY Protocol.
* This factory can be placed in front of any other connection factory
* to process the proxy line before the normal protocol handling
- *
+ *
* @see http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
*/
public class ProxyConnectionFactory extends AbstractConnectionFactory
@@ -48,7 +48,7 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
private final String _next;
/* ------------------------------------------------------------ */
- /** Proxy Connection Factory that uses the next ConnectionFactory
+ /** Proxy Connection Factory that uses the next ConnectionFactory
* on the connector as the next protocol
*/
public ProxyConnectionFactory()
@@ -56,13 +56,13 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
super("proxy");
_next=null;
}
-
+
public ProxyConnectionFactory(String nextProtocol)
{
super("proxy");
_next=nextProtocol;
}
-
+
@Override
public Connection newConnection(Connector connector, EndPoint endp)
{
@@ -71,7 +71,7 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
{
for (Iterator i = connector.getProtocols().iterator();i.hasNext();)
{
- String p=i.next();
+ String p=i.next();
if (getProtocol().equalsIgnoreCase(p))
{
next=i.next();
@@ -79,16 +79,16 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
}
}
}
-
+
return new ProxyConnection(endp,connector,next);
}
-
+
public static class ProxyConnection extends AbstractConnection
{
// 0 1 2 3 4 5 6
// 98765432109876543210987654321
// PROXY P R.R.R.R L.L.L.L R Lrn
-
+
private final int[] __size = {29,23,21,13,5,3,1};
private final Connector _connector;
private final String _next;
@@ -96,7 +96,7 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
private final String[] _field=new String[6];
private int _fields;
private int _length;
-
+
protected ProxyConnection(EndPoint endp, Connector connector, String next)
{
super(endp,connector.getExecutor());
@@ -110,9 +110,9 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
super.onOpen();
fillInterested();
}
-
+
@Override
- public void onFillable()
+ public void onFillable()
{
try
{
@@ -125,7 +125,7 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
buffer=BufferUtil.allocate(size);
else
BufferUtil.clear(buffer);
-
+
// Read data
int fill=getEndPoint().fill(buffer);
if (fill<0)
@@ -138,15 +138,15 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
fillInterested();
return;
}
-
+
_length+=fill;
if (_length>=108)
{
- LOG.warn("PROXY line too long {}",getEndPoint());
+ LOG.warn("PROXY line too long {} for {}",_length,getEndPoint());
close();
return;
}
-
+
// parse fields
while (buffer.hasRemaining())
{
@@ -160,61 +160,60 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
}
else if (b<' ')
{
- LOG.warn("Bad char {}",getEndPoint());
+ LOG.warn("Bad character {} for {}",b&0xFF,getEndPoint());
close();
return;
}
else
+ {
_builder.append((char)b);
+ }
}
else
{
if (b=='\n')
break loop;
- LOG.warn("Bad CRLF {}",getEndPoint());
+ LOG.warn("Bad CRLF for {}",getEndPoint());
close();
return;
-
}
}
}
-
+
// Check proxy
if (!"PROXY".equals(_field[0]))
{
- LOG.warn("Bad PROXY {}",getEndPoint());
+ LOG.warn("Not PROXY protocol for {}",getEndPoint());
close();
return;
}
-
- // Extract Addresses
+
+ // Extract Addresses
InetSocketAddress remote=new InetSocketAddress(_field[2],Integer.parseInt(_field[4]));
InetSocketAddress local =new InetSocketAddress(_field[3],Integer.parseInt(_field[5]));
-
+
// Create the next protocol
ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next);
if (connectionFactory == null)
{
- LOG.info("{} next protocol '{}'",getEndPoint(), _next);
+ LOG.info("Next protocol '{}' for {}",_next,getEndPoint());
close();
return;
}
EndPoint endPoint = new ProxyEndPoint(getEndPoint(),remote,local);
- Connection newConnection = connectionFactory.newConnection(_connector, endPoint);
+ Connection newConnection = connectionFactory.newConnection(_connector, endPoint);
endPoint.upgrade(newConnection);
}
- catch (Throwable e)
+ catch (Throwable x)
{
- LOG.warn("Bad PROXY {} {}",e.toString(),getEndPoint());
- LOG.debug(e);
+ LOG.warn("PROXY error for "+getEndPoint(),x);
close();
}
}
}
-
-
+
public static class ProxyEndPoint implements EndPoint
{
private final EndPoint _endp;
@@ -233,7 +232,7 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
{
return _endp.isOptimizedForDirectBuffers();
}
-
+
public InetSocketAddress getLocalAddress()
{
return _local;
@@ -304,6 +303,12 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
_endp.fillInterested(callback);
}
+ @Override
+ public boolean isFillInterested()
+ {
+ return _endp.isFillInterested();
+ }
+
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
{
_endp.write(callback,buffers);
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
index 8fc2a59106..c9432d880a 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java
@@ -18,23 +18,16 @@
package org.eclipse.jetty.server;
-import static org.hamcrest.Matchers.anyOf;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
+import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -49,6 +42,14 @@ import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.util.IO;
import org.junit.Test;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+
public class ServerConnectorTest
{
public static class ReuseInfoHandler extends AbstractHandler
@@ -79,9 +80,9 @@ public class ServerConnectorTest
{
t.printStackTrace(out);
}
-
+
out.printf("socket.getReuseAddress() = %b%n",socket.getReuseAddress());
-
+
baseRequest.setHandled(true);
}
}
@@ -97,7 +98,7 @@ public class ServerConnectorTest
return new URI(String.format("http://%s:%d/",host,port));
}
- private String getResponse(URI uri) throws MalformedURLException, IOException
+ private String getResponse(URI uri) throws IOException
{
HttpURLConnection http = (HttpURLConnection)uri.toURL().openConnection();
assertThat("Valid Response Code",http.getResponseCode(),anyOf(is(200),is(404)));
@@ -130,7 +131,7 @@ public class ServerConnectorTest
String response = getResponse(uri);
assertThat("Response",response,containsString("connector.getReuseAddress() = true"));
assertThat("Response",response,containsString("connector._reuseAddress() = true"));
-
+
// Java on Windows is incapable of propagating reuse-address this to the opened socket.
if (!OS.IS_WINDOWS)
{
@@ -166,7 +167,7 @@ public class ServerConnectorTest
String response = getResponse(uri);
assertThat("Response",response,containsString("connector.getReuseAddress() = true"));
assertThat("Response",response,containsString("connector._reuseAddress() = true"));
-
+
// Java on Windows is incapable of propagating reuse-address this to the opened socket.
if (!OS.IS_WINDOWS)
{
@@ -202,7 +203,7 @@ public class ServerConnectorTest
String response = getResponse(uri);
assertThat("Response",response,containsString("connector.getReuseAddress() = false"));
assertThat("Response",response,containsString("connector._reuseAddress() = false"));
-
+
// Java on Windows is incapable of propagating reuse-address this to the opened socket.
if (!OS.IS_WINDOWS)
{
@@ -214,4 +215,23 @@ public class ServerConnectorTest
server.stop();
}
}
+
+ @Test
+ public void testAddFirstConnectionFactory() throws Exception
+ {
+ Server server = new Server();
+ ServerConnector connector = new ServerConnector(server);
+ server.addConnector(connector);
+
+ HttpConnectionFactory http = new HttpConnectionFactory();
+ connector.addConnectionFactory(http);
+ ProxyConnectionFactory proxy = new ProxyConnectionFactory();
+ connector.addFirstConnectionFactory(proxy);
+
+ Collection factories = connector.getConnectionFactories();
+ assertEquals(2, factories.size());
+ assertSame(proxy, factories.iterator().next());
+ assertEquals(2, connector.getBeans(ConnectionFactory.class).size());
+ assertEquals(proxy.getProtocol(), connector.getDefaultProtocol());
+ }
}
--
cgit v1.2.3