Merge branch 'jetty-9.4.x' into jetty-10.0.x

This commit is contained in:
WalkerWatch 2018-08-07 21:18:25 -04:00
commit b249021b6d
8 changed files with 71 additions and 82 deletions

View File

@ -79,10 +79,10 @@ public class WebListenerAnnotation extends DiscoveredAnnotation
HttpSessionAttributeListener.class.isAssignableFrom(clazz) || HttpSessionAttributeListener.class.isAssignableFrom(clazz) ||
HttpSessionIdListener.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) 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())); ListenerHolder h = _context.getServletHandler().newListenerHolder(new Source(Source.Origin.ANNOTATION, clazz.getName()));
h.setListener(listener); h.setListener(listener);
_context.getServletHandler().addListener(h); _context.getServletHandler().addListener(h);

View File

@ -38,7 +38,6 @@ import org.eclipse.jetty.client.util.BufferingResponseListener;
import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.QuotedCSV; 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.Log;
import org.eclipse.jetty.util.log.Logger; 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 int DEFAULT_MAX_CONTENT_LENGTH = 16*1024;
public static final Logger LOG = Log.getLogger(AuthenticationProtocolHandler.class); 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 HttpClient client;
private final int maxContentLength; private final int maxContentLength;
private final ResponseNotifier notifier; private final ResponseNotifier notifier;
private static final Pattern CHALLENGE_PATTERN = Pattern.compile("(?<schemeOnly>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)|(?:(?<scheme>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s+)?(?:(?<token68>[a-zA-Z0-9\\-._~+\\/]+=*)|(?<paramName>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s*=\\s*(?:(?<paramValue>.*)))");
protected AuthenticationProtocolHandler(HttpClient client, int maxContentLength) protected AuthenticationProtocolHandler(HttpClient client, int maxContentLength)
{ {
this.client = client; this.client = client;
@ -84,78 +79,49 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
} }
protected List<HeaderInfo> getHeaderInfo(String header) throws IllegalArgumentException
protected List<HeaderInfo> getHeaderInfo(String value) throws IllegalArgumentException
{ {
String header = value;
List<HeaderInfo> headerInfos = new ArrayList<>(); List<HeaderInfo> headerInfos = new ArrayList<>();
Matcher m;
while(true) for(String value : new QuotedCSV(true, header))
{ {
Matcher m = MULTIPLE_CHALLENGE_PATTERN.matcher(header); m = CHALLENGE_PATTERN.matcher(value);
if (m.matches()) if (m.matches())
{ {
headerInfos.add(newHeaderInfo(m.group(1))); if(m.group("schemeOnly") != null)
header = m.group(2); {
} headerInfos.add(new HeaderInfo(getAuthorizationHeader(), m.group(1), new HashMap<>()));
else continue;
{ }
headerInfos.add(newHeaderInfo(header));
break; 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<String, String> 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; return headerInfos;
} }
protected HeaderInfo newHeaderInfo(String value) throws IllegalArgumentException
{
String type;
Map<String,String> 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<String, String> parseParameters(String wwwAuthenticate) throws IllegalArgumentException
{
Map<String, String> 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 private class AuthenticationListener extends BufferingResponseListener
{ {

View File

@ -31,12 +31,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.Authentication; 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.AuthenticationStore;
import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.client.api.ContentResponse; 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;
import org.eclipse.jetty.client.api.Response.Listener; import org.eclipse.jetty.client.api.Response.Listener;
import org.eclipse.jetty.client.api.Result; 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.BasicAuthentication;
import org.eclipse.jetty.client.util.DeferredContentProvider; import org.eclipse.jetty.client.util.DeferredContentProvider;
import org.eclipse.jetty.client.util.DigestAuthentication; 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("name").equals("value"));
Assert.assertTrue(headerInfo.getParameter("other").equals("value2")); 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.assertEquals(headerInfos.size(), 2);
Assert.assertTrue(headerInfos.get(0).getType().equalsIgnoreCase("Scheme")); Assert.assertTrue(headerInfos.get(0).getType().equalsIgnoreCase("Scheme"));
Assert.assertTrue(headerInfos.get(0).getParameter("nAmE").equals("value")); 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("realm").equals("thermostat3="));
Assert.assertTrue(headerInfoList.get(2).getParameter("nonce").equals("9523570528=")); Assert.assertTrue(headerInfoList.get(2).getParameter("nonce").equals("9523570528="));
} }
@Test
public void testSingleChallangeLooksLikeMultipleChallenge()
{
AuthenticationProtocolHandler aph = new WWWAuthenticationProtocolHandler(client);
List<HeaderInfo> 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="));
}
} }

View File

@ -23,10 +23,6 @@
<configuration> <configuration>
<mainClass>org.eclipse.jetty.http2.server.H2SpecServer</mainClass> <mainClass>org.eclipse.jetty.http2.server.H2SpecServer</mainClass>
<skip>${skipTests}</skip> <skip>${skipTests}</skip>
<!-- TODO: remove the exclusion when upgrading to h2spec 2.1.1+ -->
<excludeSpecs>
<excludeSpec>5.1 - closed: Sends a DATA frame</excludeSpec>
</excludeSpecs>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>

View File

@ -62,4 +62,13 @@ public class ListenerHolder extends BaseHolder<EventListener>
super.doStart(); super.doStart();
} }
@Override
public String toString()
{
return super.toString()+(_listener == null?"":": "+getClassName());
}
} }

View File

@ -190,7 +190,7 @@ public class GzipHandlerTest
for (Enumeration<String> e = req.getParameterNames(); e.hasMoreElements(); ) for (Enumeration<String> e = req.getParameterNames(); e.hasMoreElements(); )
{ {
String n = e.nextElement(); String n = e.nextElement();
response.getWriter().printf("%s: %s%n",n,req.getParameter(n)); response.getWriter().printf("%s: %s\n",n,req.getParameter(n));
} }
} }
} }

View File

@ -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. * @return the timeout in milliseconds for idle timeout.
*/ */

View File

@ -893,7 +893,7 @@
<plugin> <plugin>
<groupId>com.github.madgnome</groupId> <groupId>com.github.madgnome</groupId>
<artifactId>h2spec-maven-plugin</artifactId> <artifactId>h2spec-maven-plugin</artifactId>
<version>0.3</version> <version>0.4</version>
</plugin> </plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>