From 201a11a899c707d71aed00f2de6ca23811f22a3d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 18 Aug 2017 11:38:55 +1000 Subject: [PATCH 01/12] Issue #1556 Timing attack --- .../jetty/util/security/Credential.java | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java index ba6c75370a1..1d1ae472ff9 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java @@ -72,51 +72,47 @@ public abstract class Credential implements Serializable } /** - *

Utility method that replaces String.equals() to avoid timing attacks.

+ *

Utility method that replaces String.equals() to avoid timing attacks. + * The length of the loop executed will always be the length of the unknown credential

* - * @param s1 the first string to compare - * @param s2 the second string to compare + * @param known the first string to compare (should be known string) + * @param unknown the second string to compare (should be the unknown string) * @return whether the two strings are equal */ - protected static boolean stringEquals(String s1, String s2) + protected static boolean stringEquals(String known, String unknown) { - if (s1 == s2) + if (known == unknown) return true; - if (s1 == null || s2 == null) + if (known == null || unknown == null) return false; boolean result = true; - int l1 = s1.length(); - int l2 = s2.length(); - if (l1 != l2) - result = false; - int l = Math.min(l1, l2); - for (int i = 0; i < l; ++i) - result &= s1.charAt(i) == s2.charAt(i); - return result; + int l1 = known.length(); + int l2 = unknown.length(); + for (int i = 0; i < l2; ++i) + result &= known.charAt(i%l1) == unknown.charAt(i); + return result && l1 == l2; } /** - *

Utility method that replaces Arrays.equals() to avoid timing attacks.

+ *

Utility method that replaces Arrays.equals() to avoid timing attacks. + * The length of the loop executed will always be the length of the unknown credential

* - * @param b1 the first byte array to compare - * @param b2 the second byte array to compare + * @param known the first byte array to compare (should be known value) + * @param unknown the second byte array to compare (should be unknown value) * @return whether the two byte arrays are equal */ - protected static boolean byteEquals(byte[] b1, byte[] b2) + protected static boolean byteEquals(byte[] known, byte[] unknown) { - if (b1 == b2) + if (known == unknown) return true; - if (b1 == null || b2 == null) + if (known == null || unknown == null) return false; boolean result = true; - int l1 = b1.length; - int l2 = b2.length; - if (l1 != l2) - result = false; - int l = Math.min(l1, l2); - for (int i = 0; i < l; ++i) - result &= b1[i] == b2[i]; - return result; + int l1 = known.length; + int l2 = unknown.length; + for (int i = 0; i < l2; ++i) + result &= known[i%l1] == unknown[i]; + return result && l1 == l2; } /** From a3c3d735ab698cdf0f0409ee68b0cc3ad50511c9 Mon Sep 17 00:00:00 2001 From: Dell Green Date: Fri, 25 Aug 2017 17:49:22 +0100 Subject: [PATCH 02/12] Issues #1717 DoSFilter remotePort tracker loadId delimiter added between address and port for ipv4 and ipv6 Signed-off-by: Dell Green --- .../org/eclipse/jetty/servlets/DoSFilter.java | 14 +- .../eclipse/jetty/servlets/DoSFilterTest.java | 59 +++ .../servlets/mocks/MockFilterConfig.java | 50 +++ .../mocks/MockHttpServletRequest.java | 389 ++++++++++++++++++ 4 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockFilterConfig.java create mode 100644 jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockHttpServletRequest.java diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java index 9920479b944..e5c9606d783 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java @@ -583,7 +583,7 @@ public class DoSFilter implements Filter } else { - loadId = isRemotePort() ? (request.getRemoteAddr() + request.getRemotePort()) : request.getRemoteAddr(); + loadId = isRemotePort() ? createRemotePortId(request) : request.getRemoteAddr(); type = USER_IP; } } @@ -616,6 +616,10 @@ public class DoSFilter implements Filter return tracker; } + + + + public void addToRateTracker (RateTracker tracker) { _rateTrackers.put(tracker.getId(), tracker); @@ -1356,4 +1360,12 @@ public class DoSFilter implements Filter super.onTimeout(event); } } + + private String createRemotePortId(final ServletRequest request) { + final String addr = request.getRemoteAddr(); + final int port = request.getRemotePort(); + if (addr.contains(":")) return "[" + addr + "]:" + port; + return addr + ":" + port; + } + } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java index bbbe09bb5e2..73c0cbcf0de 100644 --- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/DoSFilterTest.java @@ -18,10 +18,17 @@ package org.eclipse.jetty.servlets; +import java.net.InetAddress; +import java.net.InetSocketAddress; import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.servlets.DoSFilter.RateTracker; +import org.eclipse.jetty.servlets.mocks.MockFilterConfig; +import org.eclipse.jetty.servlets.mocks.MockHttpServletRequest; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; @@ -34,6 +41,41 @@ public class DoSFilterTest extends AbstractDoSFilterTest { startServer(DoSFilter.class); } + + + @Test + public void testRemotePortLoadIdCreation_ipv6() throws ServletException { + final ServletRequest request = newMockHttpServletRequest("::192.9.5.5", 12345); + DoSFilter doSFilter = new DoSFilter(); + doSFilter.init(new MockFilterConfig()); + doSFilter.setRemotePort(true); + + try { + RateTracker tracker = doSFilter.getRateTracker(request); + Assert.assertEquals("[::192.9.5.5]:12345", tracker.getId()); + } finally { + doSFilter.stopScheduler(); + } + } + + + @Test + public void testRemotePortLoadIdCreation_ipv4() throws ServletException { + final ServletRequest request = newMockHttpServletRequest("127.0.0.1", 12345); + DoSFilter doSFilter = new DoSFilter(); + doSFilter.init(new MockFilterConfig()); + doSFilter.setRemotePort(true); + + try { + RateTracker tracker = doSFilter.getRateTracker(request); + Assert.assertEquals("127.0.0.1:12345", tracker.getId()); + } finally { + doSFilter.stopScheduler(); + } + } + + + @Test public void testRateIsRateExceeded() throws InterruptedException @@ -87,4 +129,21 @@ public class DoSFilterTest extends AbstractDoSFilterTest } return exceeded; } + + + + private HttpServletRequest newMockHttpServletRequest(final String remoteAddr, + final int remotePort) { + return new MockHttpServletRequest() { + @Override + public String getRemoteAddr() { + return remoteAddr; + } + + @Override + public int getRemotePort() { + return remotePort; + } + }; + } } diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockFilterConfig.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockFilterConfig.java new file mode 100644 index 00000000000..5083fa88cdf --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockFilterConfig.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.servlets.mocks; + +import java.util.Collections; +import java.util.Enumeration; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import org.eclipse.jetty.server.handler.ContextHandler; + + +public class MockFilterConfig implements FilterConfig { + + @Override + public String getFilterName() { + return ""; + } + + @Override + public ServletContext getServletContext() { + return new ContextHandler.StaticContext(); + } + + @Override + public String getInitParameter(String string) { + return null; + } + + @Override + public Enumeration getInitParameterNames() { + return Collections.emptyEnumeration(); + } + +} diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockHttpServletRequest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockHttpServletRequest.java new file mode 100644 index 00000000000..1af3d7c0cc9 --- /dev/null +++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/mocks/MockHttpServletRequest.java @@ -0,0 +1,389 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.servlets.mocks; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Map; +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpUpgradeHandler; +import javax.servlet.http.Part; + + +public class MockHttpServletRequest implements HttpServletRequest { + + @Override + public String getAuthType() { + return ""; + } + + @Override + public Cookie[] getCookies() { + return new Cookie[0]; + } + + @Override + public long getDateHeader(String string) { + return 0; + } + + @Override + public String getHeader(String string) { + return ""; + } + + @Override + public Enumeration getHeaders(String string) { + return Collections.emptyEnumeration(); + } + + @Override + public Enumeration getHeaderNames() { + return Collections.emptyEnumeration(); + } + + @Override + public int getIntHeader(String string) { + return 0; + } + + @Override + public String getMethod() { + return ""; + } + + @Override + public String getPathInfo() { + return ""; + } + + @Override + public String getPathTranslated() { + return ""; + } + + @Override + public String getContextPath() { + return ""; + } + + @Override + public String getQueryString() { + return ""; + } + + @Override + public String getRemoteUser() { + return ""; + } + + @Override + public boolean isUserInRole(String string) { + return false; + } + + @Override + public Principal getUserPrincipal() { + return null; + } + + @Override + public String getRequestedSessionId() { + return ""; + } + + @Override + public String getRequestURI() { + return ""; + } + + @Override + public StringBuffer getRequestURL() { + return new StringBuffer(0); + } + + @Override + public String getServletPath() { + return ""; + } + + @Override + public HttpSession getSession(boolean bln) { + return null; + } + + @Override + public HttpSession getSession() { + return null; + } + + @Override + public String changeSessionId() { + return ""; + } + + @Override + public boolean isRequestedSessionIdValid() { + return false; + } + + @Override + public boolean isRequestedSessionIdFromCookie() { + return false; + } + + @Override + public boolean isRequestedSessionIdFromURL() { + return false; + } + + @Override + public boolean isRequestedSessionIdFromUrl() { + return false; + } + + @Override + public boolean authenticate(HttpServletResponse hsr) throws IOException, ServletException { + return false; + } + + @Override + public void login(String string, String string1) throws ServletException { + } + + @Override + public void logout() throws ServletException { + } + + @Override + public Collection getParts() throws IOException, ServletException { + return Collections.emptyList(); + } + + @Override + public Part getPart(String string) throws IOException, ServletException { + return null; + } + + @Override + public T upgrade(Class type) throws IOException, ServletException { + return null; + } + + @Override + public Object getAttribute(String string) { + return null; + } + + @Override + public Enumeration getAttributeNames() { + return Collections.emptyEnumeration(); + } + + @Override + public String getCharacterEncoding() { + return ""; + } + + @Override + public void setCharacterEncoding(String string) throws UnsupportedEncodingException { + } + + @Override + public int getContentLength() { + return 0; + } + + @Override + public long getContentLengthLong() { + return 0; + } + + @Override + public String getContentType() { + return ""; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + return null; + } + + @Override + public String getParameter(String string) { + return ""; + } + + @Override + public Enumeration getParameterNames() { + return Collections.emptyEnumeration(); + } + + @Override + public String[] getParameterValues(String string) { + return new String[0]; + } + + @Override + public Map getParameterMap() { + return Collections.emptyMap(); + } + + @Override + public String getProtocol() { + return ""; + } + + @Override + public String getScheme() { + return ""; + } + + @Override + public String getServerName() { + return ""; + } + + @Override + public int getServerPort() { + return 0; + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new StringReader("")); + } + + @Override + public String getRemoteAddr() { + return ""; + } + + @Override + public String getRemoteHost() { + return ""; + } + + @Override + public void setAttribute(String string, Object o) { + } + + @Override + public void removeAttribute(String string) { + } + + @Override + public Locale getLocale() { + return Locale.ENGLISH; + } + + @Override + public Enumeration getLocales() { + return Collections.emptyEnumeration(); + } + + @Override + public boolean isSecure() { + return false; + } + + @Override + public RequestDispatcher getRequestDispatcher(String string) { + return null; + } + + @Override + public String getRealPath(String string) { + return ""; + } + + @Override + public int getRemotePort() { + return 0; + } + + @Override + public String getLocalName() { + return ""; + } + + @Override + public String getLocalAddr() { + return ""; + } + + @Override + public int getLocalPort() { + return 0; + } + + @Override + public ServletContext getServletContext() { + return null; + } + + @Override + public AsyncContext startAsync() throws IllegalStateException { + return null; + } + + @Override + public AsyncContext startAsync(ServletRequest sr, ServletResponse sr1) throws IllegalStateException { + return null; + } + + @Override + public boolean isAsyncStarted() { + return false; + } + + @Override + public boolean isAsyncSupported() { + return false; + } + + @Override + public AsyncContext getAsyncContext() { + return null; + } + + @Override + public DispatcherType getDispatcherType() { + return null; + } + +} From b680d1deea7ea45a57a9cdb1b05ed52c0c4ff6a7 Mon Sep 17 00:00:00 2001 From: Lucas Fairchild-Madar Date: Fri, 25 Aug 2017 11:23:08 -0700 Subject: [PATCH 03/12] Allow for configuring WebSocketClient JVM lifecycle Signed-off-by: Lucas Fairchild-Madar --- .../websocket/client/WebSocketClient.java | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index 8f4149ddd03..17eff77fbba 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -77,6 +77,9 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont private final int id = ThreadLocalRandom.current().nextInt(); + // defaults to true for backwards compatibility + private boolean stopAtShutdown = true; + /** * Instantiate a WebSocketClient with defaults */ @@ -378,21 +381,37 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont if (LOG.isDebugEnabled()) LOG.debug("connect websocket {} to {}",websocket,toUri); - init(); - WebSocketUpgradeRequest wsReq = new WebSocketUpgradeRequest(this,httpClient,request); wsReq.setUpgradeListener(upgradeListener); return wsReq.sendAsync(); } + @Override + protected void doStart() throws Exception + { + if (LOG.isDebugEnabled()) + LOG.debug("Starting {}",this); + + if (isStopAtShutdown()) { + ShutdownThread.register(this); + } + + super.doStart(); + + if (LOG.isDebugEnabled()) + LOG.debug("Started {}",this); + } + @Override protected void doStop() throws Exception { if (LOG.isDebugEnabled()) LOG.debug("Stopping {}",this); - ShutdownThread.deregister(this); + if (isStopAtShutdown()) { + ShutdownThread.deregister(this); + } super.doStop(); @@ -550,14 +569,6 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont return httpClient.getSslContextFactory(); } - private synchronized void init() throws IOException - { - if (!ShutdownThread.isRegistered(this)) - { - ShutdownThread.register(this); - } - } - /** * Factory method for new ConnectionManager * @@ -694,6 +705,32 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont return this.httpClient; } + /** + * Set JVM shutdown behavior. + * @param stop If true, this client instance will be explicitly stopped when the + * JVM is shutdown. Otherwise the application is responsible for maintaining the WebSocketClient lifecycle. + * @see Runtime#addShutdownHook(Thread) + * @see ShutdownThread + */ + public void setStopAtShutdown(boolean stop) + { + if (stop) + { + if (!stopAtShutdown && isStarted()) { + ShutdownThread.register(this); + } + } + else { + ShutdownThread.deregister(this); + } + + stopAtShutdown = stop; + } + + public boolean isStopAtShutdown() { + return stopAtShutdown; + } + @Override public String toString() { From 7d1d7a9724640ed121799d9f811908446d8bb0f9 Mon Sep 17 00:00:00 2001 From: Lucas Fairchild-Madar Date: Fri, 25 Aug 2017 12:33:41 -0700 Subject: [PATCH 04/12] Preserve delayed initialization semantics Signed-off-by: Lucas Fairchild-Madar --- .../websocket/client/WebSocketClient.java | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index 17eff77fbba..ec7a769cdfa 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -381,37 +381,21 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont if (LOG.isDebugEnabled()) LOG.debug("connect websocket {} to {}",websocket,toUri); + init(); + WebSocketUpgradeRequest wsReq = new WebSocketUpgradeRequest(this,httpClient,request); wsReq.setUpgradeListener(upgradeListener); return wsReq.sendAsync(); } - @Override - protected void doStart() throws Exception - { - if (LOG.isDebugEnabled()) - LOG.debug("Starting {}",this); - - if (isStopAtShutdown()) { - ShutdownThread.register(this); - } - - super.doStart(); - - if (LOG.isDebugEnabled()) - LOG.debug("Started {}",this); - } - @Override protected void doStop() throws Exception { if (LOG.isDebugEnabled()) LOG.debug("Stopping {}",this); - if (isStopAtShutdown()) { - ShutdownThread.deregister(this); - } + ShutdownThread.deregister(this); super.doStop(); @@ -569,6 +553,14 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont return httpClient.getSslContextFactory(); } + private synchronized void init() throws IOException + { + if (isStopAtShutdown() && !ShutdownThread.isRegistered(this)) + { + ShutdownThread.register(this); + } + } + /** * Factory method for new ConnectionManager * @@ -716,7 +708,7 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont { if (stop) { - if (!stopAtShutdown && isStarted()) { + if (!stopAtShutdown && isStarted() && !ShutdownThread.isRegistered(this)) { ShutdownThread.register(this); } } From 84ff1e3a66df6fd6040d5947dcea8be407eec9f8 Mon Sep 17 00:00:00 2001 From: Lucas Fairchild-Madar Date: Fri, 25 Aug 2017 12:35:45 -0700 Subject: [PATCH 05/12] Matching coding style; block potential race condition Signed-off-by: Lucas Fairchild-Madar --- .../eclipse/jetty/websocket/client/WebSocketClient.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index ec7a769cdfa..ac5b9377e05 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -704,15 +704,17 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont * @see Runtime#addShutdownHook(Thread) * @see ShutdownThread */ - public void setStopAtShutdown(boolean stop) + public synchronized void setStopAtShutdown(boolean stop) { if (stop) { - if (!stopAtShutdown && isStarted() && !ShutdownThread.isRegistered(this)) { + if (!stopAtShutdown && isStarted() && !ShutdownThread.isRegistered(this)) + { ShutdownThread.register(this); } } - else { + else + { ShutdownThread.deregister(this); } From b24c4e1a8a2b6ca95a057f5a569b6dd675d013dd Mon Sep 17 00:00:00 2001 From: Lucas Fairchild-Madar Date: Fri, 25 Aug 2017 12:36:48 -0700 Subject: [PATCH 06/12] further match coding style --- .../eclipse/jetty/websocket/client/WebSocketClient.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java index ac5b9377e05..67c75d0838f 100644 --- a/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java +++ b/jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/WebSocketClient.java @@ -709,19 +709,16 @@ public class WebSocketClient extends ContainerLifeCycle implements WebSocketCont if (stop) { if (!stopAtShutdown && isStarted() && !ShutdownThread.isRegistered(this)) - { ShutdownThread.register(this); - } } else - { ShutdownThread.deregister(this); - } stopAtShutdown = stop; } - public boolean isStopAtShutdown() { + public boolean isStopAtShutdown() + { return stopAtShutdown; } From afaa170cd98c050472396a8dadb4cdb20acf9d3d Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 30 Aug 2017 16:40:58 +1000 Subject: [PATCH 07/12] Issue #1116 Allow empty HTTP header value --- .../src/main/java/org/eclipse/jetty/http/HttpGenerator.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index e59b981af49..01973bf547b 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -600,10 +600,6 @@ public class HttpGenerator for (int f=0;f Date: Wed, 30 Aug 2017 16:42:47 +1000 Subject: [PATCH 08/12] Issue #1116 Allow empty HTTP header value --- .../org/eclipse/jetty/http/HttpGenerator.java | 4 -- .../jetty/http/HttpGeneratorClientTest.java | 41 +++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java index 6a3a35e8548..0c1672360fb 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java @@ -560,10 +560,6 @@ public class HttpGenerator for (int f=0;f Date: Thu, 31 Aug 2017 10:49:58 -0400 Subject: [PATCH 09/12] Updating connectory documentation. Resolves #1784 --- .../startup/screen-empty-base-listconfig.adoc | 12 +- .../screen-http-webapp-deploy-listconfig.adoc | 19 +- .../startup/screen-http-webapp-deploy.adoc | 16 +- .../startup/screen-list-logging-modules.adoc | 2 +- .../startup/startup-modules.adoc | 19 +- .../connectors/configuring-connectors.adoc | 284 +++++++++++++++++- .../main/docbkx-stylesheet/html/docbook.xsl | 8 +- 7 files changed, 308 insertions(+), 52 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc index d236b24db46..b1d726d36a4 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc @@ -16,7 +16,7 @@ [source, screen, subs="{sub-order}"] .... -[mybase]$ java -jar /opt/jetty-distribution/start.jar --list-config +[mybase]$ java -jar $JETTY_HOME/start.jar --list-config Java Environment: ----------------- @@ -28,7 +28,7 @@ Java Environment: java.runtime.name = Java(TM) SE Runtime Environment java.runtime.version = 1.8.0_92-b14 java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/ - user.dir = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase + user.dir = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase user.language = en user.country = US @@ -36,14 +36,14 @@ Jetty Environment: ----------------- jetty.version = {VERSION} jetty.tag.version = master - jetty.home = /Users/staff/installs/repository/jetty-distribution-9.4.0 - jetty.base = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase + jetty.home = /Users/staff/installs/repository/jetty-distribution-{VERSION} + jetty.base = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase Config Search Order: -------------------- - ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase - ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-9.4.0 + ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase + ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-{VERSION} JVM Arguments: diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc index 42852f088e6..fcd6b25d1a3 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc @@ -16,7 +16,7 @@ [source, screen, subs="{sub-order}"] .... -[mybase]$ java -jar ../start.jar --list-config +[mybase]$ java -jar $JETTY_HOME/start.jar --list-config Java Environment: ----------------- @@ -28,7 +28,7 @@ Java Environment: java.runtime.name = Java(TM) SE Runtime Environment java.runtime.version = 1.8.0_92-b14 java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/ - user.dir = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase + user.dir = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase user.language = en user.country = US @@ -36,14 +36,14 @@ Jetty Environment: ----------------- jetty.version = {VERSION} jetty.tag.version = master - jetty.home = /Users/staff/installs/repository/jetty-distribution-9.4.0 - jetty.base = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase + jetty.home = /Users/staff/installs/repository/jetty-distribution-{VERSION} + jetty.base = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase Config Search Order: -------------------- - ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase - ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-9.4.0 + ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase + ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-{VERSION} JVM Arguments: @@ -81,7 +81,8 @@ Note: order presented here is how they would appear on the classpath. Jetty Active XMLs: ------------------ - ${jetty.home}/etc/jetty.xml - ${jetty.home}/etc/jetty-deploy.xml - ${jetty.home}/etc/jetty-http.xml +${jetty.home}/etc/jetty.xml +${jetty.home}/etc/jetty-webapp.xml +${jetty.home}/etc/jetty-deploy.xml +${jetty.home}/etc/jetty-http.xml .... diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc index 4fab86e5e05..cabdb76adb8 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc @@ -16,11 +16,13 @@ [source, screen, subs="{sub-order}"] .... -[mybase]$ java -jar ../start.jar --add-to-start=http,webapp,deploy -INFO : webapp initialised in ${jetty.base}/start.d/webapp.ini -INFO : server initialised (transitively) in ${jetty.base}/start.d/server.ini -INFO : http initialised in ${jetty.base}/start.d/http.ini -INFO : deploy initialised in ${jetty.base}/start.d/deploy.ini -MKDIR: ${jetty.base}/webapps -INFO : Base directory was modified +[mybase]$ java -jar $JETTY_HOME/start.jar --add-to-start=http,webapp,deploy +INFO : webapp initialized in ${jetty.base}/start.ini +INFO : server transitively enabled, ini template available with --add-to-start=server +INFO : security transitively enabled +INFO : servlet transitively enabled +INFO : http initialized in ${jetty.base}/start.ini +INFO : deploy initialized in ${jetty.base}/start.ini +MKDIR : ${jetty.base}/webapps +INFO : Base directory was modified .... diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc index 6f4e9181826..f88ac6c408a 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc @@ -16,7 +16,7 @@ [source, screen, subs="{sub-order}"] .... -[mybase]$ java -jar ../start.jar --list-modules=logging,-internal +[mybase]$ java -jar $JETTY_HOME/start.jar --list-modules=logging,-internal Available Modules: ================== diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc index 6e308896d0d..874bbf65b80 100644 --- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc @@ -18,7 +18,8 @@ === Managing Startup Modules The standard Jetty Distribution ships with several modules defined in `${jetty.home}/modules/`. -These modules allow flexibility for implementations and make configuration a much more plug-and-play set up. +Modules interact with Jetty XML files to configure options and parameters for the server and are the primary configuration method for Jetty distributions. +Modules allow flexibility for implementations and their plug-and-play nature makes adding or removing server functionality virtually painless. [[enabling-modules]] ==== Enabling Modules @@ -28,27 +29,27 @@ The default distribution has a co-mingled `${jetty.home}` and `${jetty.base}` wh It is highly encouraged that you learn about the differences in link:#startup-base-and-home[Jetty Base vs Jetty Home] and take full advantage of this setup. ____ -Jetty ships with many modules defined in `${jetty.home}/modules`. Enabling a module is a simple process: simply add the `--add-to-start` syntax on the command line. Doing this will enable the module and any dependent modules. -An example of this, with a new, empty, base directory. -We can see from this output, that the directory is new. +An example of this with a new, empty, base directory: + +If we try to start the Jetty server with no configuration or modules enabled, it will promptly exit: include::screen-empty-base.adoc[] -Lets see what the configuration looks like so far: +By using the `--list-config` parameter to our startup command, we can see that there are no modules enabled and no Jetty XML files are active: include::screen-empty-base-listconfig.adoc[] -Lets try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector. +Let's try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector. include::screen-http-webapp-deploy.adoc[] -This created the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files. -Additionally, where needed, Jetty enabled any module dependencies and added their module ini template properties. +This creates the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files. +Additionally, where needed, Jetty enabled any module dependencies. -Lets see what it looks like configuration wise. +Now that we have added some modules to our server, let's run `--list-config` again to review our new configuration. include::screen-http-webapp-deploy-listconfig.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc index 5f9719ae1f7..b4b114da1ff 100644 --- a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc +++ b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc @@ -24,13 +24,274 @@ Configuring a connector is a combination of configuring the following: * Services the connector uses (for example: executors, schedulers). * Connection factories that instantiate and configure the protocol for an accepted connection. -Jetty primarily uses a single connector type called link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector]. +Typically connectors require very little configuration aside from setting the listening port, and enabling `X-Forwarded-For` customization when applicable. +Additional settings, including construction your own constructor Jetty XML files, are for expert configuration only. + +==== Enabling Connectors + +Out of the box, Jetty provides several link:#startup-modules[modules] for enabling different types of connectors, from HTTP to HTTPS, HTTP/2, and others. +If you startup Jetty with the `--list-modules=connector` command, you can see a list of all available connector modules: + +[source, screen, subs="{sub-order}"] +.... +[mybase]$ java -jar $JETTY_HOME/start.jar --list-modules=connector + +Available Modules: +================== +tags: [connector] + +Modules for tag 'connector': +---------------------------- + + Module: http + : Enables a HTTP connector on the server. + : By default HTTP/1 is support, but HTTP2C can + : be added to the connector with the http2c module. + Tags: connector, http + Depend: server + XML: etc/jetty-http.xml + Enabled: ${jetty.base}/start.ini + + Module: http-forwarded + : Adds a forwarded request customizer to the HTTP Connector + : to process forwarded-for style headers from a proxy. + Tags: connector + Depend: http + XML: etc/jetty-http-forwarded.xml + + Module: http2 + : Enables HTTP2 protocol support on the TLS(SSL) Connector, + : using the ALPN extension to select which protocol to use. + Tags: connector, http2, http, ssl + Depend: ssl, alpn + LIB: lib/http2/*.jar + XML: etc/jetty-http2.xml + + Module: http2c + : Enables the HTTP2C protocol on the HTTP Connector + : The connector will accept both HTTP/1 and HTTP/2 connections. + Tags: connector, http2, http + Depend: http + LIB: lib/http2/*.jar + XML: etc/jetty-http2c.xml + + Module: https + : Adds HTTPS protocol support to the TLS(SSL) Connector + Tags: connector, https, http, ssl + Depend: ssl + Optional: http-forwarded, http2 + XML: etc/jetty-https.xml + + Module: proxy-protocol-ssl + : Enables the Proxy Protocol on the TLS(SSL) Connector. + : http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt + : This allows a Proxy operating in TCP mode to transport + : details of the proxied connection to the server. + : Both V1 and V2 versions of the protocol are supported. + Tags: connector, ssl + Depend: ssl + XML: etc/jetty-proxy-protocol-ssl.xml + + Module: ssl + : Enables a TLS(SSL) Connector on the server. + : This may be used for HTTPS and/or HTTP2 by enabling + : the associated support modules. + Tags: connector, ssl + Depend: server + XML: etc/jetty-ssl.xml + XML: etc/jetty-ssl-context.xml + + Module: unixsocket + : Enables a Unix Domain Socket Connector that can receive + : requests from a local proxy and/or SSL offloader (eg haproxy) in either + : HTTP or TCP mode. Unix Domain Sockets are more efficient than + : localhost TCP/IP connections as they reduce data copies, avoid + : needless fragmentation and have better dispatch behaviours. + : When enabled with corresponding support modules, the connector can + : accept HTTP, HTTPS or HTTP2C traffic. + Tags: connector + Depend: server + LIB: lib/jetty-unixsocket-${jetty.version}.jar + LIB: lib/jnr/*.jar + XML: etc/jetty-unixsocket.xml + + Module: unixsocket-forwarded + : Adds a forwarded request customizer to the HTTP configuration used + : by the Unix Domain Socket connector, for use when behind a proxy operating + : in HTTP mode that adds forwarded-for style HTTP headers. Typically this + : is an alternate to the Proxy Protocol used mostly for TCP mode. + Tags: connector + Depend: unixsocket-http + XML: etc/jetty-unixsocket-forwarded.xml + + Module: unixsocket-http + : Adds a HTTP protocol support to the Unix Domain Socket connector. + : It should be used when a proxy is forwarding either HTTP or decrypted + : HTTPS traffic to the connector and may be used with the + : unix-socket-http2c modules to upgrade to HTTP/2. + Tags: connector, http + Depend: unixsocket + XML: etc/jetty-unixsocket-http.xml + + Module: unixsocket-http2c + : Adds a HTTP2C connetion factory to the Unix Domain Socket Connector + : It can be used when either the proxy forwards direct + : HTTP/2C (unecrypted) or decrypted HTTP/2 traffic. + Tags: connector, http2 + Depend: unixsocket-http + LIB: lib/http2/*.jar + XML: etc/jetty-unixsocket-http2c.xml + + Module: unixsocket-proxy-protocol + : Enables the proxy protocol on the Unix Domain Socket Connector + : http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt + : This allows information about the proxied connection to be + : efficiently forwarded as the connection is accepted. + : Both V1 and V2 versions of the protocol are supported and any + : SSL properties may be interpreted by the unixsocket-secure + : module to indicate secure HTTPS traffic. Typically this + : is an alternate to the forwarded module. + Tags: connector + Depend: unixsocket + XML: etc/jetty-unixsocket-proxy-protocol.xml + + Module: unixsocket-secure + : Enable a secure request customizer on the HTTP Configuration + : used by the Unix Domain Socket Connector. + : This looks for a secure scheme transported either by the + : unixsocket-forwarded, unixsocket-proxy-protocol or in a + : HTTP2 request. + Tags: connector + Depend: unixsocket-http + XML: etc/jetty-unixsocket-secure.xml +... +.... + +To enable a connector, simply activate the associated module. +Below is an example of activating both the `http` and `https` modules in a fresh link:#startup-base-and-home[Jetty base] using the link:#start-vs-startd[start.d directory]: + +[source, screen, subs="{sub-order}"] +.... +[mybase] java -jar $JETTY_HOME/start.jar --create-startd +MKDIR : ${jetty.base}/start.d +INFO : Base directory was modified + +[mybase] java -jar $JETTY_HOME/start.jar --add-to-start=http,https +INFO : server transitively enabled, ini template available with --add-to-start=server +INFO : http initialized in ${jetty.base}/start.d/http.ini +INFO : https initialized in ${jetty.base}/start.d/https.ini +INFO : ssl transitively enabled, ini template available with --add-to-start=ssl +MKDIR : ${jetty.base}/etc +COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore +INFO : Base directory was modified +[mybase] tree +. +├── etc +│   └── keystore +└── start.d + ├── http.ini + └── https.ini +.... + +When the `http` and `https` modules were activated, so too were any modules they were dependent on, in this case `server` and `ssl`, as well as any dependencies for those modules, such as the `etc` and `ketystore` directories for `ssl`. + +At this point the server has been configured with connectors for both HTTP and HTTPS and can be started: + +[source, screen, subs="{sub-order}"] +.... +[mybase] java -jar $JETTY_HOME/start.jar +2017-08-31 10:19:58.855:INFO::main: Logging initialized @372ms to org.eclipse.jetty.util.log.StdErrLog +2017-08-31 10:19:59.076:INFO:oejs.Server:main: jetty-9.4.6.v20170531 +2017-08-31 10:19:59.125:INFO:oejs.AbstractConnector:main: Started ServerConnector@421e98e0{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} +2017-08-31 10:19:59.150:INFO:oejus.SslContextFactory:main: x509=X509@5315b42e(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore) +2017-08-31 10:19:59.151:INFO:oejus.SslContextFactory:main: x509=X509@5d624da6(mykey,h=[],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore) +2017-08-31 10:19:59.273:INFO:oejs.AbstractConnector:main: Started ServerConnector@2b98378d{SSL,[ssl, http/1.1]}{0.0.0.0:8443} +2017-08-31 10:19:59.274:INFO:oejs.Server:main: Started @791ms +.... + +When modules are enabled, they are loaded with several default options. +These can be changed by editing the associated module ini file in the `start.d` directory (or the associated lines in `server.ini` if your implementation does not use `start.d`). +For example, if we examine the `http.ini` file in our `start.d` directory created above, we will see the following settings: + +[source, screen, subs="{sub-order}"] +.... +# --------------------------------------- +# Module: http +# Enables a HTTP connector on the server. +# By default HTTP/1 is support, but HTTP2C can +# be added to the connector with the http2c module. +# --------------------------------------- +--module=http + +### HTTP Connector Configuration + +## Connector host/address to bind to +# jetty.http.host=0.0.0.0 + +## Connector port to listen on +# jetty.http.port=8080 + +## Connector idle timeout in milliseconds +# jetty.http.idleTimeout=30000 + +## Connector socket linger time in seconds (-1 to disable) +# jetty.http.soLingerTime=-1 + +## Number of acceptors (-1 picks default based on number of cores) +# jetty.http.acceptors=-1 + +## Number of selectors (-1 picks default based on number of cores) +# jetty.http.selectors=-1 + +## ServerSocketChannel backlog (0 picks platform default) +# jetty.http.acceptorQueueSize=0 + +## Thread priority delta to give to acceptor threads +# jetty.http.acceptorPriorityDelta=0 + +## HTTP Compliance: RFC7230, RFC2616, LEGACY +# jetty.http.compliance=RFC7230 +.... + +To make a change to these settings, uncomment the line (by removing the #) and change the property to the desired value. +For example, if you wanted to change the HTTP port to 5231, you would edit the line as follows: + +[source, screen, subs="{sub-order}"] +.... +... +## Connector port to listen on +jetty.http.port=5231 +... +.... + +Now when the server is started, HTTP connections will enter on port 5231: + +[source, screen, subs="{sub-order}"] +.... +[mybase] java -jar ../start.jar +2017-08-31 10:31:32.955:INFO::main: Logging initialized @366ms to org.eclipse.jetty.util.log.StdErrLog +2017-08-31 10:31:33.109:INFO:oejs.Server:main: jetty-9.4.6.v20170531 +2017-08-31 10:31:33.146:INFO:oejs.AbstractConnector:main: Started ServerConnector@2ef9b8bc{HTTP/1.1,[http/1.1]}{0.0.0.0:5231} +... +2017-08-31 10:31:33.263:INFO:oejs.Server:main: Started @675ms +.... + +Every module has their own set of configuration options, and reviewing them all is recommended. +For additional information on the module system, please refer to our documentation on link:#startup-modules[Startup Modules]. ____ [NOTE] +Editing these module files is the recommended way to edit the configuration of your server. +Making changes to the associated Jetty XML file for connectors is *not* recommended, and is for advanced users only. +If you do wish to edit Jetty XML, please see our section on managing link:#[Jetty Home and Jetty Base] to ensure your Jetty Home remains a standard of truth for your implementation. +____ + +==== Advanced Configuration + +Jetty primarily uses a single connector type called link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector]. + Prior to Jetty 9, the type of the connector specified both the protocol and the implementation used; for example, selector-based non blocking I/O vs blocking I/O, or SSL connector vs non-SSL connector. Jetty 9 has a single selector-based non-blocking I/O connector, and a collection of link:{JDURL}/org/eclipse/jetty/server/ConnectionFactory.html[`ConnectionFactories`] now configure the protocol on the connector. -____ The standard Jetty distribution comes with the following Jetty XML files that create and configure connectors; you should examine them as you read this section: @@ -48,15 +309,6 @@ link:{GITBROWSEURL}/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-server/src/main/config/etc/jetty-alpn.xml[`jetty-alpn.xml`]:: Adds an link:{JDURL}/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.html[`ALPNServerConnectionFactory`] to the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] configured by `jetty-ssl.xml` which allows the one SSL connector to support multiple protocols with the ALPN extension used to select the protocol to be used for each connection. -Typically connectors require very little configuration aside from setting the listening port (see link:#jetty-connectors-network-settings[Network Settings]), and enabling `X-Forwarded-For` customization when applicable. (see link:#jetty-connectors-http-configuration[HTTP Configuration]). -Additional settings are for expert configuration only. - -____ -[NOTE] -All the connectors discussed in this chapter can be enabled in the Jetty Distribution by enabling them via the module system. -Please refer to our chapter on link:#startup-modules[Managing Startup Modules] for more information. -____ - ==== Constructing a ServerConnector The services a link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] instance uses are set by constructor injection and once instantiated cannot be changed. @@ -79,9 +331,9 @@ You can see the other arguments that can be passed when constructing a `ServerCo Typically the defaults are sufficient for almost all deployments. [[jetty-connectors-network-settings]] -==== Network Settings. +==== Network Settings -You configure connector network settings by calling setters on the connector before it is started. +You can configure connector network settings by calling setters on the connector before it is started. For example, you can set the port with the Jetty XML: [source, xml, subs="{sub-order}"] @@ -107,7 +359,7 @@ Thus typically the port is set within Jetty XML, but uses the `Property` element ---- -The network settings that you can set on the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] include: +The network settings available for configuration on the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] include: .Connector Configuration [width="100%",cols="22%,78%",options="header",] @@ -238,13 +490,13 @@ These headers can be interpreted by an instance of link:{JDURL}/org/eclipse/jett ===== Proxy Protocol -The http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt[Proxy Protocol] is a de facto standard created by HAProxy and used by environments such as Amazon Elastic Cloud. +The http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt[Proxy Protocol] is the _de facto_ standard created by HAProxy and used by environments such as Amazon Elastic Cloud. This mechanism is independent of any protocol, so it can be used for HTTP2, TLS etc. The information about the client connection is sent as a small data frame on each newly established connection. In Jetty, this protocol can be handled by the link:{JDURL}/org/eclipse/jetty/server/ProxyConnectionFactory.html[`ProxyConnectionFactory`] which parses the data frame and then instantiates the next `ConnectionFactory` on the connection with an end point that has been customized with the data obtained about the original client connection. The connection factory can be added to any link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] and should be the first link:{JDURL}/org/eclipse/jetty/server/ConnectionFactory.html[`ConnectionFactory`]. -An example of adding the factory to a HTTP connector is: +An example of adding the factory to a HTTP connector is shown below: [source, xml, subs="{sub-order}"] ---- diff --git a/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl b/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl index eeadaa81667..44ebe4d4a1c 100644 --- a/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl +++ b/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl @@ -129,13 +129,13 @@ xmlns:date="http://exslt.org/dates-and-times" -