From 288f2e1f5190b2efa9ba998e3e4f864921a374cc Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Thu, 21 Jan 2016 16:53:04 -0700 Subject: [PATCH 01/21] Fixing javadoc: Invalid member type qualification --- .../jetty/client/util/MultiPartContentProvider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java index 8da77960545..bf6013a475c 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/MultiPartContentProvider.java @@ -116,8 +116,8 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple *

The {@code Content-Type} of this part will be obtained from:

* * @@ -136,8 +136,8 @@ public class MultiPartContentProvider extends AbstractTypedContentProvider imple *

The {@code Content-Type} of this part will be obtained from:

* * From 734d18fb93da4f363acca96bd78ca6ca0f4b577b Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 22 Jan 2016 14:07:51 -0700 Subject: [PATCH 02/21] 486394 - MultipartConfig.fileSizeThreshold default of 0 should always create a file + Refactored fileSizeThreshold logic so that a configuration value of 0 is always create file (negative) is never create file positive is tested against filesize --- .../util/MultiPartInputStreamParser.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java index 946d708c307..95fbcd635ef 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartInputStreamParser.java @@ -40,6 +40,7 @@ import java.util.List; import java.util.Locale; import javax.servlet.MultipartConfigElement; +import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.Part; import org.eclipse.jetty.util.log.Log; @@ -112,7 +113,7 @@ public class MultiPartInputStreamParser if (MultiPartInputStreamParser.this._config.getMaxFileSize() > 0 && _size + 1 > MultiPartInputStreamParser.this._config.getMaxFileSize()) throw new IllegalStateException ("Multipart Mime part "+_name+" exceeds max filesize"); - if (MultiPartInputStreamParser.this._config.getFileSizeThreshold() > 0 && _size + 1 > MultiPartInputStreamParser.this._config.getFileSizeThreshold() && _file==null) + if (_file == null && MultiPartInputStreamParser.this.isFileNeeded(_size + 1)) createFile(); _out.write(b); @@ -125,7 +126,7 @@ public class MultiPartInputStreamParser if (MultiPartInputStreamParser.this._config.getMaxFileSize() > 0 && _size + length > MultiPartInputStreamParser.this._config.getMaxFileSize()) throw new IllegalStateException ("Multipart Mime part "+_name+" exceeds max filesize"); - if (MultiPartInputStreamParser.this._config.getFileSizeThreshold() > 0 && _size + length > MultiPartInputStreamParser.this._config.getFileSizeThreshold() && _file==null) + if (_file == null && MultiPartInputStreamParser.this.isFileNeeded(_size + length)) createFile(); _out.write(bytes, offset, length); @@ -429,6 +430,31 @@ public class MultiPartInputStreamParser } + /** + * Test to determine if the file content sizes exceeds the {@link MultipartConfig#fileSizeThreshold()} + * necessary to produce a file on disk + *

+ * Configured {@link MultipartConfig#fileSizeThreshold()} of 0 is always true, negative is always false, + * all other configurations are tested against size parameter + * + * @param size the file size to test against. + * @return true if file is needed, false otherwise + */ + protected boolean isFileNeeded(long size) + { + if (_config.getFileSizeThreshold() < 0) + { + // Negative file size threshold means no file, ever + return false; + } + if (_config.getFileSizeThreshold() == 0) + { + // 0 means always create a file + return true; + } + return size > _config.getFileSizeThreshold(); + } + /** * Parse, if necessary, the multipart stream. * From e3dd0cb83be2df2470595b272dc740a538b7c8f1 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 25 Jan 2016 13:23:41 -0700 Subject: [PATCH 03/21] 486511 - Server.getURI() returns wrong scheme on SSL/HTTPS --- .../main/java/org/eclipse/jetty/server/Server.java | 6 ++++-- .../ssl/SSLSelectChannelConnectorLoadTest.java | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index 1d81e6a615f..51c145d6067 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -654,7 +654,6 @@ public class Server extends HandlerWrapper implements Attributes /** * @return The URI of the first {@link NetworkConnector} and first {@link ContextHandler}, or null */ - @SuppressWarnings("resource") public URI getURI() { NetworkConnector connector=null; @@ -674,7 +673,10 @@ public class Server extends HandlerWrapper implements Attributes try { - String scheme=connector.getDefaultConnectionFactory().getProtocol().startsWith("SSL-")?"https":"http"; + String protocol = connector.getDefaultConnectionFactory().getProtocol(); + String scheme="http"; + if (protocol.startsWith("SSL-") || protocol.equals("SSL")) + scheme = "https"; String host=connector.getHost(); if (context!=null && context.getVirtualHosts()!=null && context.getVirtualHosts().length>0) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java index b5fde36ef73..a6d8aedcc38 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java @@ -18,12 +18,16 @@ package org.eclipse.jetty.server.ssl; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.net.URI; import java.security.KeyStore; import java.util.Arrays; import java.util.Random; @@ -91,6 +95,15 @@ public class SSLSelectChannelConnectorLoadTest server.stop(); server.join(); } + + @Test + public void testGetURI() + { + URI uri = server.getURI(); + assertThat("Server.uri.scheme", uri.getScheme(), is("https")); + assertThat("Server.uri.port", uri.getPort(), is(connector.getLocalPort())); + assertThat("Server.uri.path", uri.getPath(), is("/")); + } @Test public void testLongLivedConnections() throws Exception From 1aef09acc2ad6fad040c56e6826a83e9749fdedd Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 27 Jan 2016 11:55:00 -0700 Subject: [PATCH 04/21] 486604 - Add debug logging of ErrorPageErrorHandler logic --- .../jetty/server/handler/ErrorHandler.java | 6 ++- .../jetty/servlet/ErrorPageErrorHandler.java | 52 +++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java index 016c57885a4..1106826bbcf 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java @@ -39,7 +39,6 @@ import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.ByteArrayISO8859Writer; -import org.eclipse.jetty.util.Jetty; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -101,6 +100,11 @@ public class ErrorHandler extends AbstractHandler return; } } + } else { + if (LOG.isDebugEnabled()) + { + LOG.debug("No Error Page mapping for request({} {}) (using default)",request.getMethod(),request.getRequestURI()); + } } } diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java index 976fb34ac2e..f7ad40d2325 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java @@ -30,17 +30,20 @@ import javax.servlet.http.HttpServletRequest; import org.eclipse.jetty.server.Dispatcher; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; /* ------------------------------------------------------------ */ /** Error Page Error Handler * * An ErrorHandler that maps exceptions and status codes to URIs for dispatch using * the internal ERROR style of dispatch. - * */ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler.ErrorPageMapper { public final static String GLOBAL_ERROR_PAGE = "org.eclipse.jetty.server.error_page.global"; + private static final Logger LOG = Log.getLogger(ErrorPageErrorHandler.class); + enum PageLookupTechnique{ THROWABLE, STATUS_CODE, GLOBAL } protected ServletContext _servletContext; private final Map _errorPages= new HashMap(); // code or exception to URL @@ -56,11 +59,15 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. { String error_page= null; + PageLookupTechnique pageSource = null; + Throwable th= (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION); // Walk the cause hierarchy while (error_page == null && th != null ) { + pageSource = PageLookupTechnique.THROWABLE; + Class exClass=th.getClass(); error_page= (String)_errorPages.get(exClass.getName()); @@ -76,13 +83,17 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. th=(th instanceof ServletException)?((ServletException)th).getRootCause():null; } + Integer errorStatusCode = null; + if (error_page == null) { + pageSource = PageLookupTechnique.STATUS_CODE; + // look for an exact code match - Integer code=(Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE); - if (code!=null) + errorStatusCode = (Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE); + if (errorStatusCode!=null) { - error_page= (String)_errorPages.get(Integer.toString(code)); + error_page= (String)_errorPages.get(Integer.toString(errorStatusCode)); // if still not found if ((error_page == null) && (_errorPageList != null)) @@ -91,7 +102,7 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. for (int i = 0; i < _errorPageList.size(); i++) { ErrorCodeRange errCode = (ErrorCodeRange) _errorPageList.get(i); - if (errCode.isInRange(code)) + if (errCode.isInRange(errorStatusCode)) { error_page = errCode.getUri(); break; @@ -103,7 +114,38 @@ public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler. //try servlet 3.x global error page if (error_page == null) + { + pageSource = PageLookupTechnique.GLOBAL; error_page = _errorPages.get(GLOBAL_ERROR_PAGE); + } + + if (LOG.isDebugEnabled()) + { + StringBuilder dbg = new StringBuilder(); + dbg.append("getErrorPage("); + dbg.append(request.getMethod()).append(' '); + dbg.append(request.getRequestURI()); + dbg.append(") => error_page=").append(error_page); + switch (pageSource) + { + case THROWABLE: + dbg.append(" (from Throwable "); + dbg.append(th.getClass().getName()); + dbg.append(')'); + LOG.debug(dbg.toString(),th); + break; + case STATUS_CODE: + dbg.append(" (from status code "); + dbg.append(errorStatusCode); + dbg.append(')'); + LOG.debug(dbg.toString()); + break; + case GLOBAL: + dbg.append(" (from global default)"); + LOG.debug(dbg.toString()); + break; + } + } return error_page; } From 83bc83a99d35193745b606497124915255b95fac Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Wed, 27 Jan 2016 11:55:08 -0700 Subject: [PATCH 05/21] 486674 - Quickstart path attribute normalization should be based on longest path match --- .../jetty/quickstart/AttributeNormalizer.java | 270 +++++++++++++----- .../quickstart/AttributeNormalizerTest.java | 87 ++++-- 2 files changed, 264 insertions(+), 93 deletions(-) diff --git a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java index 84943863243..0f893b42f1b 100644 --- a/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java +++ b/jetty-quickstart/src/main/java/org/eclipse/jetty/quickstart/AttributeNormalizer.java @@ -19,9 +19,19 @@ package org.eclipse.jetty.quickstart; import java.io.File; +import java.io.IOException; import java.net.URI; import java.net.URL; +import java.nio.file.FileSystems; +import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.log.Log; @@ -30,7 +40,8 @@ import org.eclipse.jetty.util.resource.Resource; /** * Normalize Attribute to String. - *

Replaces and expands: + *

+ * Replaces and expands: *