diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java index 55dd55bdf42..5478d5637ab 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/WebListenerAnnotation.java @@ -79,10 +79,10 @@ public class WebListenerAnnotation extends DiscoveredAnnotation HttpSessionAttributeListener.class.isAssignableFrom(clazz) || HttpSessionIdListener.class.isAssignableFrom(clazz)) { - java.util.EventListener listener = (java.util.EventListener)_context.getServletContext().createInstance(clazz); - MetaData metaData = _context.getMetaData(); + MetaData metaData = _context.getMetaData(); if (metaData.getOrigin(clazz.getName()+".listener") == Origin.NotSet) { + java.util.EventListener listener = (java.util.EventListener)_context.getServletContext().createInstance(clazz); ListenerHolder h = _context.getServletHandler().newListenerHolder(new Source(Source.Origin.ANNOTATION, clazz.getName())); h.setListener(listener); _context.getServletHandler().addListener(h); diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java index 6d390f87c08..b0441b334cb 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java @@ -38,7 +38,6 @@ import org.eclipse.jetty.client.util.BufferingResponseListener; import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.QuotedCSV; -import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -46,16 +45,12 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler { public static final int DEFAULT_MAX_CONTENT_LENGTH = 16*1024; public static final Logger LOG = Log.getLogger(AuthenticationProtocolHandler.class); - - private static final Pattern PARAM_PATTERN = Pattern.compile("([^=]+)=(.*)"); - private static final Pattern TYPE_PATTERN = Pattern.compile("([^\\s]+)(\\s+(.*))?"); - private static final Pattern MULTIPLE_CHALLENGE_PATTERN = Pattern.compile("(.*?)\\s*,\\s*([^=\\s,]+(\\s+[^=\\s].*)?)"); - private static final Pattern BASE64_PATTERN = Pattern.compile("[\\+\\-\\.\\/\\dA-Z_a-z~]+=*"); - private final HttpClient client; private final int maxContentLength; private final ResponseNotifier notifier; + private static final Pattern CHALLENGE_PATTERN = Pattern.compile("(?[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)|(?:(?[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s+)?(?:(?[a-zA-Z0-9\\-._~+\\/]+=*)|(?[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s*=\\s*(?:(?.*)))"); + protected AuthenticationProtocolHandler(HttpClient client, int maxContentLength) { this.client = client; @@ -82,80 +77,51 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler // Return new instances every time to keep track of the response content return new AuthenticationListener(); } - - - protected List getHeaderInfo(String value) throws IllegalArgumentException + + protected List getHeaderInfo(String header) throws IllegalArgumentException { - String header = value; List headerInfos = new ArrayList<>(); - - while(true) + Matcher m; + + for(String value : new QuotedCSV(true, header)) { - Matcher m = MULTIPLE_CHALLENGE_PATTERN.matcher(header); + m = CHALLENGE_PATTERN.matcher(value); if (m.matches()) { - headerInfos.add(newHeaderInfo(m.group(1))); - header = m.group(2); - } - else - { - headerInfos.add(newHeaderInfo(header)); - break; + if(m.group("schemeOnly") != null) + { + headerInfos.add(new HeaderInfo(getAuthorizationHeader(), m.group(1), new HashMap<>())); + continue; + } + + if (m.group("scheme") != null) + { + headerInfos.add(new HeaderInfo(getAuthorizationHeader(), m.group("scheme"), new HashMap<>())); + } + + if (headerInfos.isEmpty()) + throw new IllegalArgumentException("Parameters without auth-scheme"); + + Map authParams = headerInfos.get(headerInfos.size() - 1).getParameters(); + if (m.group("paramName") != null) + { + String paramVal = QuotedCSV.unquote(m.group("paramValue")); + authParams.put(m.group("paramName"), paramVal); + } + else if (m.group("token68") != null) + { + if (!authParams.isEmpty()) + throw new IllegalArgumentException("token68 after auth-params"); + + authParams.put("base64", m.group("token68")); + } } } - + return headerInfos; } - protected HeaderInfo newHeaderInfo(String value) throws IllegalArgumentException - { - String type; - Map params = new HashMap<>(); - - Matcher m = TYPE_PATTERN.matcher(value); - if (m.matches()) - { - type = m.group(1); - if (m.group(2) != null) - params = parseParameters(m.group(3)); - } - else - { - throw new IllegalArgumentException("Invalid Authentication Format"); - } - - return new HeaderInfo(getAuthorizationHeader(), type, params); - } - - protected Map parseParameters(String wwwAuthenticate) throws IllegalArgumentException - { - Map result = new HashMap<>(); - - Matcher b64 = BASE64_PATTERN.matcher(wwwAuthenticate); - if (b64.matches()) - { - result.put("base64", wwwAuthenticate); - return result; - } - - QuotedCSV parts = new QuotedCSV(false, wwwAuthenticate); - for (String part : parts) - { - Matcher params = PARAM_PATTERN.matcher(part); - if (params.matches()) - { - String name = StringUtil.asciiToLowerCase(params.group(1)); - String value = (params.group(2)==null) ? "" : params.group(2); - result.put(name, value); - } - else - { - throw new IllegalArgumentException("Invalid Authentication Format"); - } - } - return result; - } private class AuthenticationListener extends BufferingResponseListener { diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java index aa6249d33fe..095c858e681 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java @@ -31,12 +31,12 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.IntFunction; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.api.Authentication; +import org.eclipse.jetty.client.api.Authentication.HeaderInfo; import org.eclipse.jetty.client.api.AuthenticationStore; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.ContentResponse; @@ -44,7 +44,6 @@ import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Response.Listener; import org.eclipse.jetty.client.api.Result; -import org.eclipse.jetty.client.api.Authentication.HeaderInfo; import org.eclipse.jetty.client.util.BasicAuthentication; import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.client.util.DigestAuthentication; @@ -705,7 +704,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest Assert.assertTrue(headerInfo.getParameter("name").equals("value")); Assert.assertTrue(headerInfo.getParameter("other").equals("value2")); - headerInfos = aph.getHeaderInfo("Scheme name=value, Scheme2 name=value2"); + headerInfos = aph.getHeaderInfo(", , , , ,,,Scheme name=value, ,,Scheme2 name=value2,, ,,"); Assert.assertEquals(headerInfos.size(), 2); Assert.assertTrue(headerInfos.get(0).getType().equalsIgnoreCase("Scheme")); Assert.assertTrue(headerInfos.get(0).getParameter("nAmE").equals("value")); @@ -768,4 +767,23 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest Assert.assertTrue(headerInfoList.get(2).getParameter("realm").equals("thermostat3=")); Assert.assertTrue(headerInfoList.get(2).getParameter("nonce").equals("9523570528=")); } + + @Test + public void testSingleChallangeLooksLikeMultipleChallenge() + { + AuthenticationProtocolHandler aph = new WWWAuthenticationProtocolHandler(client); + List headerInfoList = aph.getHeaderInfo("Digest param=\",f \""); + Assert.assertEquals(1, headerInfoList.size()); + + + + headerInfoList = aph.getHeaderInfo("Digest realm=\"thermostat\", qop=\",Digest realm=hello\", nonce=\"1523430383=\""); + Assert.assertEquals(1, headerInfoList.size()); + + HeaderInfo headerInfo = headerInfoList.get(0); + Assert.assertTrue(headerInfo.getType().equalsIgnoreCase("Digest")); + Assert.assertTrue(headerInfo.getParameter("qop").equals(",Digest realm=hello")); + Assert.assertTrue(headerInfo.getParameter("realm").equals("thermostat")); + Assert.assertThat(headerInfo.getParameter("nonce"), Matchers.is("1523430383=")); + } } diff --git a/jetty-http2/http2-server/pom.xml b/jetty-http2/http2-server/pom.xml index 9e7196363c4..ab5794eabc9 100644 --- a/jetty-http2/http2-server/pom.xml +++ b/jetty-http2/http2-server/pom.xml @@ -23,10 +23,6 @@ org.eclipse.jetty.http2.server.H2SpecServer ${skipTests} - - - 5.1 - closed: Sends a DATA frame - diff --git a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java index 41986ea6011..d09e298e7e8 100644 --- a/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java +++ b/jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ListenerHolder.java @@ -62,4 +62,13 @@ public class ListenerHolder extends BaseHolder super.doStart(); } + + + @Override + public String toString() + { + return super.toString()+(_listener == null?"":": "+getClassName()); + } + + } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java index c09a43a050c..8cc05babfcf 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/GzipHandlerTest.java @@ -190,7 +190,7 @@ public class GzipHandlerTest for (Enumeration e = req.getParameterNames(); e.hasMoreElements(); ) { String n = e.nextElement(); - response.getWriter().printf("%s: %s%n",n,req.getParameter(n)); + response.getWriter().printf("%s: %s\n",n,req.getParameter(n)); } } } diff --git a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java index 8055140f223..bfc037de0d5 100644 --- a/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java +++ b/jetty-websocket/websocket-api/src/main/java/org/eclipse/jetty/websocket/api/WebSocketPolicy.java @@ -204,7 +204,7 @@ public class WebSocketPolicy } /** - * The time in ms (milliseconds) that a websocket connection mad by idle before being closed automatically. + * The time in ms (milliseconds) that a websocket connection may by idle before being closed automatically. * * @return the timeout in milliseconds for idle timeout. */ diff --git a/pom.xml b/pom.xml index 6c6f3909284..d91d2671382 100644 --- a/pom.xml +++ b/pom.xml @@ -893,7 +893,7 @@ com.github.madgnome h2spec-maven-plugin - 0.3 + 0.4