Merge branch 'master' into start-init-improvements
This commit is contained in:
commit
cf90c683cd
|
@ -665,6 +665,7 @@ public class HttpStatus
|
|||
public final static int UNSUPPORTED_MEDIA_TYPE_415 = 415;
|
||||
public final static int REQUESTED_RANGE_NOT_SATISFIABLE_416 = 416;
|
||||
public final static int EXPECTATION_FAILED_417 = 417;
|
||||
public final static int MISDIRECTED_REQUEST_421 = 421;
|
||||
public final static int UNPROCESSABLE_ENTITY_422 = 422;
|
||||
public final static int LOCKED_423 = 423;
|
||||
public final static int FAILED_DEPENDENCY_424 = 424;
|
||||
|
@ -802,6 +803,8 @@ public class HttpStatus
|
|||
REQUESTED_RANGE_NOT_SATISFIABLE(REQUESTED_RANGE_NOT_SATISFIABLE_416, "Requested Range Not Satisfiable"),
|
||||
/** <code>417 Expectation Failed</code> */
|
||||
EXPECTATION_FAILED(EXPECTATION_FAILED_417, "Expectation Failed"),
|
||||
/** <code>421 Misdirected Request(RFC7234)y</code> */
|
||||
MISDIRECTED_REQUEST(MISDIRECTED_REQUEST_421, "Misdirected Request"),
|
||||
/** <code>422 Unprocessable Entity</code> */
|
||||
UNPROCESSABLE_ENTITY(UNPROCESSABLE_ENTITY_422, "Unprocessable Entity"),
|
||||
/** <code>423 Locked</code> */
|
||||
|
|
|
@ -1496,63 +1496,6 @@ public class HttpParserTest
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyProtocol() throws Exception
|
||||
{
|
||||
ByteBuffer buffer=BufferUtil
|
||||
.toBuffer("PROXY TCP4 107.47.45.254 10.0.1.116 27689 80\015\012"
|
||||
+"GET / HTTP/1.1\015\012"
|
||||
+"Host: localhost \015\012"
|
||||
+"Connection: close\015\012"+"\015\012"+"\015\012");
|
||||
|
||||
Handler handler=new Handler();
|
||||
HttpParser parser=new HttpParser((HttpParser.RequestHandler)handler);
|
||||
parseAll(parser, buffer);
|
||||
|
||||
assertTrue(_headerCompleted);
|
||||
assertTrue(_messageCompleted);
|
||||
assertEquals("GET", _methodOrVersion);
|
||||
assertEquals("/", _uriOrStatus);
|
||||
assertEquals("HTTP/1.1", _versionOrReason);
|
||||
assertEquals("PROXY TCP4 107.47.45.254 10.0.1.116 27689 80", handler._proxy);
|
||||
assertEquals("Host", _hdr[0]);
|
||||
assertEquals("localhost", _val[0]);
|
||||
assertEquals("Connection", _hdr[1]);
|
||||
assertEquals("close", _val[1]);
|
||||
assertEquals(1, _headers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitProxyHeaderParseTest() throws Exception
|
||||
{
|
||||
Handler handler=new Handler();
|
||||
HttpParser parser=new HttpParser((HttpParser.RequestHandler)handler);
|
||||
|
||||
ByteBuffer buffer=BufferUtil.toBuffer("PROXY TCP4 207.47.45.254 10.0.1.116 27689 80\015\012");
|
||||
parser.parseNext(buffer);
|
||||
|
||||
buffer=BufferUtil.toBuffer(
|
||||
"GET / HTTP/1.1\015\012"
|
||||
+"Host: localhost \015\012"
|
||||
+"Connection: close\015\012"
|
||||
+"\015\012"
|
||||
+"\015\012");
|
||||
|
||||
parser.parseNext(buffer);
|
||||
assertTrue(_headerCompleted);
|
||||
assertTrue(_messageCompleted);
|
||||
assertEquals("GET", _methodOrVersion);
|
||||
assertEquals("/", _uriOrStatus);
|
||||
assertEquals("HTTP/1.1", _versionOrReason);
|
||||
assertEquals("PROXY TCP4 207.47.45.254 10.0.1.116 27689 80", handler._proxy);
|
||||
assertEquals("Host", _hdr[0]);
|
||||
assertEquals("localhost", _val[0]);
|
||||
assertEquals("Connection", _hdr[1]);
|
||||
assertEquals("close", _val[1]);
|
||||
assertEquals(1, _headers);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFolded() throws Exception
|
||||
{
|
||||
|
|
|
@ -43,7 +43,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
|
|||
|
||||
public AbstractHTTP2ServerConnectionFactory()
|
||||
{
|
||||
super("h2-14");
|
||||
super("h2-15","h2-14");
|
||||
}
|
||||
|
||||
public boolean isDispatchIO()
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
<Arg name="selectors" type="int"><Property name="http.selectors" default="-1"/></Arg>
|
||||
<Arg name="factories">
|
||||
<Array type="org.eclipse.jetty.server.ConnectionFactory">
|
||||
<!-- uncomment to support proxy protocol
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
|
||||
</Item>-->
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
|
||||
<Arg name="config"><Ref refid="httpConfig" /></Arg>
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
<Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg>
|
||||
<Arg name="factories">
|
||||
<Array type="org.eclipse.jetty.server.ConnectionFactory">
|
||||
<!-- uncomment to support proxy protocol
|
||||
<Item>
|
||||
<New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
|
||||
</Item>-->
|
||||
</Array>
|
||||
</Arg>
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
@ -28,11 +32,19 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
|
|||
public abstract class AbstractConnectionFactory extends ContainerLifeCycle implements ConnectionFactory
|
||||
{
|
||||
private final String _protocol;
|
||||
private final List<String> _protocols;
|
||||
private int _inputbufferSize = 8192;
|
||||
|
||||
protected AbstractConnectionFactory(String protocol)
|
||||
{
|
||||
_protocol=protocol;
|
||||
_protocols=Collections.unmodifiableList(Arrays.asList(new String[]{protocol}));
|
||||
}
|
||||
|
||||
protected AbstractConnectionFactory(String... protocols)
|
||||
{
|
||||
_protocol=protocols[0];
|
||||
_protocols=Collections.unmodifiableList(Arrays.asList(protocols));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,6 +53,12 @@ public abstract class AbstractConnectionFactory extends ContainerLifeCycle imple
|
|||
return _protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getProtocols()
|
||||
{
|
||||
return _protocols;
|
||||
}
|
||||
|
||||
public int getInputBufferSize()
|
||||
{
|
||||
return _inputbufferSize;
|
||||
|
@ -67,7 +85,7 @@ public abstract class AbstractConnectionFactory extends ContainerLifeCycle imple
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{%s}",this.getClass().getSimpleName(),hashCode(),getProtocol());
|
||||
return String.format("%s@%x%s",this.getClass().getSimpleName(),hashCode(),getProtocols());
|
||||
}
|
||||
|
||||
public static ConnectionFactory[] getFactories(SslContextFactory sslContextFactory, ConnectionFactory... factories)
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -358,17 +359,33 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
|
|||
{
|
||||
synchronized (_factories)
|
||||
{
|
||||
String key=StringUtil.asciiToLowerCase(factory.getProtocol());
|
||||
ConnectionFactory old=_factories.remove(key);
|
||||
if (old!=null)
|
||||
Set<ConnectionFactory> to_remove = new HashSet<ConnectionFactory>();
|
||||
for (String key:factory.getProtocols())
|
||||
{
|
||||
key=StringUtil.asciiToLowerCase(key);
|
||||
ConnectionFactory old=_factories.remove(key);
|
||||
if (old!=null)
|
||||
{
|
||||
if (old.getProtocol().equals(_defaultProtocol))
|
||||
_defaultProtocol=null;
|
||||
to_remove.add(old);
|
||||
}
|
||||
_factories.put(key, factory);
|
||||
}
|
||||
|
||||
// keep factories still referenced
|
||||
for (ConnectionFactory f : _factories.values())
|
||||
to_remove.remove(f);
|
||||
|
||||
// remove old factories
|
||||
for (ConnectionFactory old: to_remove)
|
||||
{
|
||||
if (old.getProtocol().equals(_defaultProtocol))
|
||||
_defaultProtocol=null;
|
||||
removeBean(old);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("{} removed {}", this, old);
|
||||
}
|
||||
_factories.put(key, factory);
|
||||
|
||||
// add new Bean
|
||||
addBean(factory);
|
||||
if (_defaultProtocol==null)
|
||||
_defaultProtocol=factory.getProtocol();
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
package org.eclipse.jetty.server;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
||||
|
@ -42,9 +44,15 @@ public interface ConnectionFactory
|
|||
{
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return A string representing the protocol name.
|
||||
* @return A string representing the primary protocol name.
|
||||
*/
|
||||
public String getProtocol();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return A list of alternative protocol names/versions including the primary protocol.
|
||||
*/
|
||||
public List<String> getProtocols();
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link Connection} with the given parameters</p>
|
||||
|
|
|
@ -52,21 +52,21 @@ public abstract class NegotiatingServerConnectionFactory extends AbstractConnect
|
|||
}
|
||||
}
|
||||
|
||||
private final List<String> protocols;
|
||||
private final List<String> negotiatedProtocols;
|
||||
private String defaultProtocol;
|
||||
|
||||
public NegotiatingServerConnectionFactory(String protocol, String... protocols)
|
||||
public NegotiatingServerConnectionFactory(String protocol, String... negotiatedProtocols)
|
||||
{
|
||||
super(protocol);
|
||||
this.protocols = new ArrayList<>();
|
||||
if (protocols != null)
|
||||
this.negotiatedProtocols = new ArrayList<>();
|
||||
if (negotiatedProtocols != null)
|
||||
{
|
||||
// Trim the values, as they may come from XML configuration.
|
||||
for (String p : protocols)
|
||||
for (String p : negotiatedProtocols)
|
||||
{
|
||||
p = p.trim();
|
||||
if (!p.isEmpty())
|
||||
this.protocols.add(p.trim());
|
||||
this.negotiatedProtocols.add(p.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,34 +83,37 @@ public abstract class NegotiatingServerConnectionFactory extends AbstractConnect
|
|||
this.defaultProtocol = dft.isEmpty() ? null : dft;
|
||||
}
|
||||
|
||||
public List<String> getProtocols()
|
||||
public List<String> getNegotiatedProtocols()
|
||||
{
|
||||
return protocols;
|
||||
return negotiatedProtocols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection newConnection(Connector connector, EndPoint endPoint)
|
||||
{
|
||||
List<String> protocols = this.protocols;
|
||||
if (protocols.isEmpty())
|
||||
List<String> negotiated = this.negotiatedProtocols;
|
||||
if (negotiated.isEmpty())
|
||||
{
|
||||
protocols = connector.getProtocols();
|
||||
Iterator<String> i = protocols.iterator();
|
||||
while (i.hasNext())
|
||||
// Generate list of protocols that we can negotiate
|
||||
negotiated = new ArrayList<>(connector.getProtocols());
|
||||
for (Iterator<String> i = negotiated.iterator();i.hasNext();)
|
||||
{
|
||||
String protocol = i.next();
|
||||
if ("ssl".equalsIgnoreCase(protocol) ||
|
||||
"alpn".equalsIgnoreCase(protocol) ||
|
||||
"npn".equalsIgnoreCase(protocol))
|
||||
// exclude SSL and negotiating protocols
|
||||
ConnectionFactory f = connector.getConnectionFactory(protocol);
|
||||
|
||||
if ((f instanceof SslConnectionFactory) ||
|
||||
(f instanceof NegotiatingServerConnectionFactory))
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if default protocol is not set, then it is the first protocol given
|
||||
String dft = defaultProtocol;
|
||||
if (dft == null && !protocols.isEmpty())
|
||||
dft = protocols.get(0);
|
||||
if (dft == null && !negotiated.isEmpty())
|
||||
dft = negotiated.get(0);
|
||||
|
||||
SSLEngine engine = null;
|
||||
EndPoint ep = endPoint;
|
||||
|
@ -123,7 +126,7 @@ public abstract class NegotiatingServerConnectionFactory extends AbstractConnect
|
|||
ep = null;
|
||||
}
|
||||
|
||||
return configure(newServerConnection(connector, endPoint, engine, protocols, dft), connector, endPoint);
|
||||
return configure(newServerConnection(connector, endPoint, engine, negotiated, dft), connector, endPoint);
|
||||
}
|
||||
|
||||
protected abstract AbstractConnection newServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol);
|
||||
|
@ -131,6 +134,6 @@ public abstract class NegotiatingServerConnectionFactory extends AbstractConnect
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{%s,%s,%s}", getClass().getSimpleName(), hashCode(), getProtocol(), getDefaultProtocol(), getProtocols());
|
||||
return String.format("%s@%x{%s,%s,%s}", getClass().getSimpleName(), hashCode(), getProtocols(), getDefaultProtocol(), getNegotiatedProtocols());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.net.InetSocketAddress;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadPendingException;
|
||||
import java.nio.channels.WritePendingException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
|
@ -44,17 +45,41 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(ProxyConnectionFactory.class);
|
||||
private final String _next;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Proxy Connection Factory that uses the next ConnectionFactory
|
||||
* on the connector as the next protocol
|
||||
*/
|
||||
public ProxyConnectionFactory()
|
||||
{
|
||||
super("proxy");
|
||||
_next=null;
|
||||
}
|
||||
|
||||
public ProxyConnectionFactory(String nextProtocol)
|
||||
{
|
||||
super("haproxy");
|
||||
super("proxy");
|
||||
_next=nextProtocol;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Connection newConnection(Connector connector, EndPoint endp)
|
||||
{
|
||||
return new ProxyConnection(endp,connector,_next);
|
||||
String next=_next;
|
||||
if (next==null)
|
||||
{
|
||||
for (Iterator<String> i = connector.getProtocols().iterator();i.hasNext();)
|
||||
{
|
||||
String p=i.next();
|
||||
if (getProtocol().equalsIgnoreCase(p))
|
||||
{
|
||||
next=i.next();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ProxyConnection(endp,connector,next);
|
||||
}
|
||||
|
||||
public static class ProxyConnection extends AbstractConnection
|
||||
|
|
|
@ -43,7 +43,7 @@ public class ProxyConnectionTest
|
|||
http.getHttpConfiguration().setRequestHeaderSize(1024);
|
||||
http.getHttpConfiguration().setResponseHeaderSize(1024);
|
||||
|
||||
ProxyConnectionFactory proxy = new ProxyConnectionFactory(http.getProtocol());
|
||||
ProxyConnectionFactory proxy = new ProxyConnectionFactory();
|
||||
|
||||
_connector = new LocalConnector(_server,null,null,null,1,proxy,http);
|
||||
_connector.setIdleTimeout(1000);
|
||||
|
|
Loading…
Reference in New Issue