Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse McConnell2012-01-13 14:21:29 +0000
committerJesse McConnell2012-01-13 14:21:29 +0000
commit16e33c3d1ebe0b9c6c45507d2d5c7045346bed29 (patch)
tree47df3c3e2987dbfdde676d11b180e7beb8b82e5d
parentfc70ea92d743b451a22ecb3486a03f958489a67f (diff)
parentc0d3266c59d12a1cc5c45715c233afd8f3a8a433 (diff)
downloadorg.eclipse.jetty.project-16e33c3d1ebe0b9c6c45507d2d5c7045346bed29.tar.gz
org.eclipse.jetty.project-16e33c3d1ebe0b9c6c45507d2d5c7045346bed29.tar.xz
org.eclipse.jetty.project-16e33c3d1ebe0b9c6c45507d2d5c7045346bed29.zip
Merge branch 'master' into jetty-8
-rw-r--r--README.txt2
-rw-r--r--example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java2
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java90
-rw-r--r--jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java1
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/Slf4jLog-mbean.properties1
-rw-r--r--jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/StdErrLog-mbean.properties1
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java41
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java3
-rw-r--r--jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java47
-rw-r--r--test-jetty-webapp/src/main/webapp/WEB-INF/web.xml2
10 files changed, 163 insertions, 27 deletions
diff --git a/README.txt b/README.txt
index 28a387764c..3412f8ff16 100644
--- a/README.txt
+++ b/README.txt
@@ -15,3 +15,5 @@ dependencies.
The tests do a lot of stress testing, and on some machines it is
necessary to set the file descriptor limit to greater than 2048
for the tests to all pass successfully.
+
+Bypass tests by building with -Dmaven.test.skip=true but note that this will not produce some test jars that are leveraged in other places in the build.
diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
index 219f9face3..6c77cd122e 100644
--- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
+++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java
@@ -53,7 +53,7 @@ public class LikeJettyXml
mbContainer.start();
server.getContainer().addEventListener(mbContainer);
server.addBean(mbContainer,true);
- mbContainer.addBean(Log.getRootLogger());
+ mbContainer.addBean(new Log());
// Setup Threadpool
QueuedThreadPool threadPool = new QueuedThreadPool();
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java
index b417ce0cc2..618639ee05 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/SslBytesServerTest.java
@@ -1,6 +1,7 @@
package org.eclipse.jetty.client;
import java.io.BufferedReader;
+import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -34,6 +35,7 @@ import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.nio.AsyncConnection;
import org.eclipse.jetty.io.nio.SslConnection;
+import org.eclipse.jetty.server.AsyncHttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
@@ -102,7 +104,7 @@ public class SslBytesServerTest extends SslBytesTest
@Override
protected AsyncConnection newPlainConnection(SocketChannel channel, AsyncEndPoint endPoint)
{
- return new org.eclipse.jetty.server.AsyncHttpConnection(this, endPoint, getServer())
+ return new AsyncHttpConnection(this, endPoint, getServer())
{
@Override
protected HttpParser newHttpParser(Buffers requestBuffers, EndPoint endPoint, HttpParser.EventHandler requestHandler)
@@ -135,21 +137,32 @@ public class SslBytesServerTest extends SslBytesTest
{
public void handle(String target, Request request, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException, ServletException
{
- request.setHandled(true);
- String contentLength = request.getHeader("Content-Length");
- if (contentLength != null)
+ try
{
- int length = Integer.parseInt(contentLength);
- ServletInputStream input = httpRequest.getInputStream();
- ServletOutputStream output = httpResponse.getOutputStream();
- byte[] buffer = new byte[32 * 1024];
- for (int i = 0; i < length; ++i)
+ request.setHandled(true);
+ String contentLength = request.getHeader("Content-Length");
+ if (contentLength != null)
{
- int read = input.read(buffer);
- if ("/echo".equals(target))
- output.write(buffer, 0, read);
+ int length = Integer.parseInt(contentLength);
+ ServletInputStream input = httpRequest.getInputStream();
+ ServletOutputStream output = httpResponse.getOutputStream();
+ byte[] buffer = new byte[32 * 1024];
+ while (length > 0)
+ {
+ int read = input.read(buffer);
+ if (read < 0)
+ throw new EOFException();
+ length -= read;
+ if (target.startsWith("/echo"))
+ output.write(buffer, 0, read);
+ }
}
}
+ catch (IOException x)
+ {
+ if (!(target.endsWith("suppress_exception")))
+ throw x;
+ }
}
});
server.start();
@@ -860,6 +873,59 @@ public class SslBytesServerTest extends SslBytesTest
// connection, and this will cause an exception in the
// server that is trying to write the data
+ TimeUnit.MILLISECONDS.sleep(500);
+ proxy.sendRSTToServer();
+
+ // Wait a while to detect spinning
+ TimeUnit.MILLISECONDS.sleep(500);
+ Assert.assertThat(sslHandles.get(), lessThan(20));
+ Assert.assertThat(sslFlushes.get(), lessThan(20));
+ Assert.assertThat(httpParses.get(), lessThan(50));
+
+ client.close();
+ }
+
+ @Test
+ public void testRequestWithBigContentReadBlockedThenReset() throws Exception
+ {
+ final SSLSocket client = newClient();
+
+ SimpleProxy.AutomaticFlow automaticProxyFlow = proxy.startAutomaticFlow();
+ client.startHandshake();
+ Assert.assertTrue(automaticProxyFlow.stop(5, TimeUnit.SECONDS));
+
+ byte[] data = new byte[128 * 1024];
+ Arrays.fill(data, (byte)'X');
+ final String content = new String(data, "UTF-8");
+ Future<Object> request = threadPool.submit(new Callable<Object>()
+ {
+ public Object call() throws Exception
+ {
+ OutputStream clientOutput = client.getOutputStream();
+ clientOutput.write(("" +
+ "GET /echo_suppress_exception HTTP/1.1\r\n" +
+ "Host: localhost\r\n" +
+ "Content-Length: " + content.length() + "\r\n" +
+ "\r\n" +
+ content).getBytes("UTF-8"));
+ clientOutput.flush();
+ return null;
+ }
+ });
+
+ // Nine TLSRecords will be generated for the request,
+ // but we write only 5 of them, so the server goes in read blocked state
+ for (int i = 0; i < 5; ++i)
+ {
+ // Application data
+ TLSRecord record = proxy.readFromClient();
+ Assert.assertEquals(TLSRecord.Type.APPLICATION, record.getType());
+ proxy.flushToServer(record, 0);
+ }
+ Assert.assertNull(request.get(5, TimeUnit.SECONDS));
+
+ // The server should be read blocked, and we send a RST
+ TimeUnit.MILLISECONDS.sleep(500);
proxy.sendRSTToServer();
// Wait a while to detect spinning
diff --git a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
index 395791ea6d..475a2da3a7 100644
--- a/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
+++ b/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java
@@ -34,6 +34,7 @@ import org.eclipse.jetty.util.component.Container.Relationship;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.log.StdErrLog;
import org.eclipse.jetty.util.thread.ShutdownThread;
/**
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/Slf4jLog-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/Slf4jLog-mbean.properties
deleted file mode 100644
index 58b10abec3..0000000000
--- a/jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/Slf4jLog-mbean.properties
+++ /dev/null
@@ -1 +0,0 @@
-Slf4jLog: SL4J log adapter
diff --git a/jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/StdErrLog-mbean.properties b/jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/StdErrLog-mbean.properties
deleted file mode 100644
index 16e56bb70b..0000000000
--- a/jetty-jmx/src/main/resources/org/eclipse/jetty/util/log/jmx/StdErrLog-mbean.properties
+++ /dev/null
@@ -1 +0,0 @@
-StdErrLog: Log adapter that logs to stderr \ No newline at end of file
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
index f402636937..67c6e7c5fb 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/CrossOriginFilter.java
@@ -18,7 +18,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -42,7 +43,14 @@ import org.eclipse.jetty.util.log.Logger;
* <ul>
* <li><b>allowedOrigins</b>, a comma separated list of origins that are
* allowed to access the resources. Default value is <b>*</b>, meaning all
- * origins</li>
+ * origins.<br />
+ * If an allowed origin contains one or more * characters (for example
+ * http://*.domain.com), then "*" characters are converted to ".*", "."
+ * characters are escaped to "\." and the resulting allowed origin
+ * interpreted as a regular expression.<br />
+ * Allowed origins can therefore be more complex expressions such as
+ * https?://*.domain.[a-z]{3} that matches http or https, multiple subdomains
+ * and any 3 letter top-level domain (.com, .net, .org, etc.).</li>
* <li><b>allowedMethods</b>, a comma separated list of HTTP methods that
* are allowed to be used when accessing the resources. Default value is
* <b>GET,POST</b></li>
@@ -229,19 +237,34 @@ public class CrossOriginFilter implements Filter
if (origin.trim().length() == 0)
continue;
- boolean allowed = false;
for (String allowedOrigin : allowedOrigins)
{
- if (allowedOrigin.equals(origin))
+ if (allowedOrigin.contains("*"))
{
- allowed = true;
- break;
+ Matcher matcher = createMatcher(origin,allowedOrigin);
+ if (matcher.matches())
+ return true;
+ }
+ else if (allowedOrigin.equals(origin))
+ {
+ return true;
}
}
- if (!allowed)
- return false;
}
- return true;
+ return false;
+ }
+
+ private Matcher createMatcher(String origin, String allowedOrigin)
+ {
+ String regex = parseAllowedWildcardOriginToRegex(allowedOrigin);
+ Pattern pattern = Pattern.compile(regex);
+ return pattern.matcher(origin);
+ }
+
+ private String parseAllowedWildcardOriginToRegex(String allowedOrigin)
+ {
+ String regex = allowedOrigin.replace(".","\\.");
+ return regex.replace("*",".*"); // we want to be greedy here to match multiple subdomains, thus we use .*
}
private boolean isSimpleRequest(HttpServletRequest request)
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
index 48bfcf391c..2b7ee1252f 100644
--- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
+++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java
@@ -62,7 +62,7 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
* <p>
* This servlet needs the jetty-util and jetty-client classes to be available to the web application.
* <p>
- * To facilitate JMX monitoring, the "HttpClient", it's "ThreadPool" and the "Logger" are set as context attributes prefixed with the servlet name.
+ * To facilitate JMX monitoring, the "HttpClient" and "ThreadPool" are set as context attributes prefixed with the servlet name.
* <p>
* The following init parameters may be used to configure the servlet:
* <ul>
@@ -127,7 +127,6 @@ public class ProxyServlet implements Servlet
if (_context != null)
{
- _context.setAttribute(config.getServletName() + ".Logger",_log);
_context.setAttribute(config.getServletName() + ".ThreadPool",_client.getThreadPool());
_context.setAttribute(config.getServletName() + ".HttpClient",_client);
}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java
index bd9bfb576b..e6c15d11b5 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/CrossOriginFilterTest.java
@@ -80,6 +80,52 @@ public class CrossOriginFilterTest
}
@Test
+ public void testSimpleRequestWithMatchingWildcardOrigin() throws Exception
+ {
+ FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
+ String origin = "http://subdomain.example.com";
+ filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "http://*.example.com");
+ tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
+
+ CountDownLatch latch = new CountDownLatch(1);
+ tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
+
+ String request = "" +
+ "GET / HTTP/1.1\r\n" +
+ "Host: localhost\r\n" +
+ "Origin: " + origin + "\r\n" +
+ "\r\n";
+ String response = tester.getResponses(request);
+ Assert.assertTrue(response.contains("HTTP/1.1 200"));
+ Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
+ Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
+ Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void testSimpleRequestWithMatchingWildcardOriginAndMultipleSubdomains() throws Exception
+ {
+ FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
+ String origin = "http://subdomain.subdomain.example.com";
+ filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "http://*.example.com");
+ tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
+
+ CountDownLatch latch = new CountDownLatch(1);
+ tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
+
+ String request = "" +
+ "GET / HTTP/1.1\r\n" +
+ "Host: localhost\r\n" +
+ "Origin: " + origin + "\r\n" +
+ "\r\n";
+ String response = tester.getResponses(request);
+ Assert.assertTrue(response.contains("HTTP/1.1 200"));
+ Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
+ Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
+ Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
+ }
+
+ @Test
public void testSimpleRequestWithMatchingOrigin() throws Exception
{
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
@@ -330,6 +376,7 @@ public class CrossOriginFilterTest
public static class ResourceServlet extends HttpServlet
{
+ private static final long serialVersionUID = 1L;
private final CountDownLatch latch;
public ResourceServlet(CountDownLatch latch)
diff --git a/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml b/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml
index 9ccb222c0a..010d10d428 100644
--- a/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml
+++ b/test-jetty-webapp/src/main/webapp/WEB-INF/web.xml
@@ -10,7 +10,7 @@
<context-param>
<param-name>org.eclipse.jetty.server.context.ManagedAttributes</param-name>
- <param-value>QoSFilter,TransparentProxy.Logger,TransparentProxy.ThreadPool,TransparentProxy.HttpClient</param-value>
+ <param-value>QoSFilter,TransparentProxy.ThreadPool,TransparentProxy.HttpClient</param-value>
</context-param>
<!-- Declare TestListener, which declares TestFilter -->

Back to the top