Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse McConnell2012-08-23 20:13:29 +0000
committerJesse McConnell2012-08-23 20:13:29 +0000
commit18cd5b455f44c3dee3fd9a0f72c78f475d4ed909 (patch)
tree233899a210c71a0ab54c0b8e6a56ab0f3a406405
parent5761c8201b7b48d32ff5c8b480d28695651c7628 (diff)
parent9173751438bf29033a8de0336d918380751a39f8 (diff)
downloadorg.eclipse.jetty.project-18cd5b455f44c3dee3fd9a0f72c78f475d4ed909.tar.gz
org.eclipse.jetty.project-18cd5b455f44c3dee3fd9a0f72c78f475d4ed909.tar.xz
org.eclipse.jetty.project-18cd5b455f44c3dee3fd9a0f72c78f475d4ed909.zip
Merge branch 'master' of ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.project
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java35
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java17
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java57
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java14
-rw-r--r--jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSocketServerTest.java6
-rw-r--r--jetty-server/src/test/resources/jetty-logging.properties3
-rw-r--r--jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java12
-rw-r--r--jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java27
-rw-r--r--jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java36
9 files changed, 162 insertions, 45 deletions
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
index 8bf464a78d..3d2d13f94e 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java
@@ -129,6 +129,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
private boolean _head = false;
private boolean _host = false;
private boolean _delayedHandling=false;
+ private boolean _earlyEOF = false;
/* ------------------------------------------------------------ */
public static AbstractHttpConnection getCurrentConnection()
@@ -395,6 +396,12 @@ public abstract class AbstractHttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
+ public boolean isEarlyEOF()
+ {
+ return _earlyEOF;
+ }
+
+ /* ------------------------------------------------------------ */
public void reset()
{
_parser.reset();
@@ -407,6 +414,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_response.recycle();
_uri.clear();
_writer=null;
+ _earlyEOF = false;
}
/* ------------------------------------------------------------ */
@@ -443,7 +451,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
{
_uri.getPort();
String path = null;
-
+
try
{
path = _uri.getDecodedPath();
@@ -454,7 +462,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
LOG.ignore(e);
path = _uri.getDecodedPath(StringUtil.__ISO_8859_1);
}
-
+
info=URIUtil.canonicalPath(path);
if (info==null && !_request.getMethod().equals(HttpMethods.CONNECT))
{
@@ -719,6 +727,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_requests);
}
+ /* ------------------------------------------------------------ */
protected void startRequest(Buffer method, Buffer uri, Buffer version) throws IOException
{
uri=uri.asImmutableBuffer();
@@ -778,6 +787,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
}
}
+ /* ------------------------------------------------------------ */
protected void parsedHeader(Buffer name, Buffer value) throws IOException
{
int ho = HttpHeaders.CACHE.getOrdinal(name);
@@ -839,6 +849,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_requestFields.add(name, value);
}
+ /* ------------------------------------------------------------ */
protected void headerComplete() throws IOException
{
_requests++;
@@ -909,6 +920,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
_delayedHandling=true;
}
+ /* ------------------------------------------------------------ */
protected void content(Buffer buffer) throws IOException
{
if (_delayedHandling)
@@ -918,6 +930,7 @@ public abstract class AbstractHttpConnection extends AbstractConnection
}
}
+ /* ------------------------------------------------------------ */
public void messageComplete(long contentLength) throws IOException
{
if (_delayedHandling)
@@ -928,6 +941,12 @@ public abstract class AbstractHttpConnection extends AbstractConnection
}
/* ------------------------------------------------------------ */
+ public void earlyEOF()
+ {
+ _earlyEOF = true;
+ }
+
+ /* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
private class RequestHandler extends HttpParser.EventHandler
@@ -996,6 +1015,18 @@ public abstract class AbstractHttpConnection extends AbstractConnection
if (LOG.isDebugEnabled())
LOG.debug("Bad request!: "+version+" "+status+" "+reason);
}
+
+ /* ------------------------------------------------------------ */
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jetty.server.server.HttpParser.EventHandler#earlyEOF()
+ */
+ @Override
+ public void earlyEOF()
+ {
+ AbstractHttpConnection.this.earlyEOF();
+ }
}
/* ------------------------------------------------------------ */
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index af5d510d86..025cf68c8a 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -24,12 +24,13 @@ import javax.servlet.ServletInputStream;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EofException;
public class HttpInput extends ServletInputStream
{
protected final AbstractHttpConnection _connection;
protected final HttpParser _parser;
-
+
/* ------------------------------------------------------------ */
public HttpInput(AbstractHttpConnection connection)
{
@@ -44,11 +45,9 @@ public class HttpInput extends ServletInputStream
@Override
public int read() throws IOException
{
- int c=-1;
- Buffer content=_parser.blockForContent(_connection.getMaxIdleTime());
- if (content!=null)
- c= 0xff & content.get();
- return c;
+ byte[] bytes = new byte[1];
+ int read = read(bytes, 0, 1);
+ return read < 0 ? -1 : 0xff & bytes[0];
}
/* ------------------------------------------------------------ */
@@ -62,6 +61,8 @@ public class HttpInput extends ServletInputStream
Buffer content=_parser.blockForContent(_connection.getMaxIdleTime());
if (content!=null)
l= content.get(b, off, len);
+ else if (_connection.isEarlyEOF())
+ throw new EofException("early EOF");
return l;
}
@@ -71,8 +72,4 @@ public class HttpInput extends ServletInputStream
{
return _parser.available();
}
-
-
-
-
}
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
index 9d51233ffa..e902ec014c 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java
@@ -30,15 +30,16 @@ import java.net.SocketException;
import java.net.URL;
import java.util.Arrays;
import java.util.Random;
-import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Exchanger;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.EofException;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.StringUtil;
@@ -50,10 +51,11 @@ import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
/**
*
@@ -148,8 +150,55 @@ public abstract class HttpServerTestBase extends HttpServerTestFixture
client.close();
}
}
-
+ @Test
+ public void testInterruptedRequest() throws Exception
+ {
+ final AtomicBoolean fourBytesRead = new AtomicBoolean(false);
+ final AtomicBoolean earlyEOFException = new AtomicBoolean(false);
+ configureServer(new AbstractHandler()
+ {
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ int contentLength = request.getContentLength();
+ ServletInputStream inputStream = request.getInputStream();
+ for (int i = 0; i < contentLength; i++)
+ {
+ try
+ {
+ inputStream.read();
+ }
+ catch (EofException e)
+ {
+ earlyEOFException.set(true);
+ throw e;
+ }
+ if (i == 3)
+ fourBytesRead.set(true);
+ }
+ }
+ });
+
+ StringBuffer request = new StringBuffer("GET / HTTP/1.0\n");
+ request.append("Host: localhost\n");
+ request.append("Content-length: 6\n\n");
+ request.append("foo");
+
+ Socket client = newSocket(HOST, _connector.getLocalPort());
+ OutputStream os = client.getOutputStream();
+
+ os.write(request.toString().getBytes());
+ os.flush();
+ client.shutdownOutput();
+ String response = readResponse(client);
+ client.close();
+
+// assertThat("response contains 200 OK", response.contains(" 500 "), is(true)); //TODO: check with gregw,
+// currently returns 200
+ assertThat("The 4th byte (-1) has not been passed to the handler", fourBytesRead.get(), is(false));
+ assertThat("EofException has been caught", earlyEOFException.get(), is(true));
+ }
/*
* Feed the server the entire request at once.
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
index 840219f66e..096ecca071 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java
@@ -17,8 +17,6 @@
//
package org.eclipse.jetty.server.ssl;
-import static org.junit.Assert.assertEquals;
-
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -26,13 +24,11 @@ import java.net.Socket;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
-
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManagerFactory;
-
import org.eclipse.jetty.io.AsyncEndPoint;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.nio.SslConnection;
@@ -41,8 +37,10 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
-import static org.junit.Assert.assertThat;
+
import static org.hamcrest.Matchers.lessThan;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
/**
* HttpServer Tester.
@@ -167,6 +165,12 @@ public class SelectChannelServerSslTest extends HttpServerTestBase
}
@Override
+ @Test
+ @Ignore("Override and ignore this test as SSLSocket.shutdownOutput() is not supported, " +
+ "but shutdownOutput() is needed by the test.")
+ public void testInterruptedRequest(){}
+
+ @Override
@Ignore
public void testAvailable() throws Exception
{
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSocketServerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSocketServerTest.java
index 4da4106b24..0c53417929 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSocketServerTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslSocketServerTest.java
@@ -77,6 +77,12 @@ public class SslSocketServerTest extends HttpServerTestBase
@Override
@Test
+ @Ignore("Override and ignore this test as SSLSocket.shutdownOutput() is not supported, " +
+ "but shutdownOutput() is needed by the test.")
+ public void testInterruptedRequest(){}
+
+ @Override
+ @Test
public void testFlush() throws Exception
{
// TODO this test uses URL, so noop for now
diff --git a/jetty-server/src/test/resources/jetty-logging.properties b/jetty-server/src/test/resources/jetty-logging.properties
new file mode 100644
index 0000000000..d8439d19ea
--- /dev/null
+++ b/jetty-server/src/test/resources/jetty-logging.properties
@@ -0,0 +1,3 @@
+# Setup default logging implementation for during testing
+org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
+org.eclipse.jetty.server.LEVEL=INFO
diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java b/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java
index b92fa35553..7a7c91c728 100644
--- a/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java
+++ b/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java
@@ -41,7 +41,8 @@ public class CommandLineBuilder
*/
public void addArg(String arg)
{
- args.add(quote(arg));
+ if (arg != null)
+ args.add(quote(arg));
}
/**
@@ -84,7 +85,8 @@ public class CommandLineBuilder
*/
public void addRawArg(String arg)
{
- args.add(arg);
+ if (arg != null)
+ args.add(arg);
}
public List<String> getArgs()
@@ -106,7 +108,7 @@ public class CommandLineBuilder
return arg;
}
StringBuilder buf = new StringBuilder();
-// buf.append('"');
+ // buf.append('"');
boolean escaped = false;
for (char c : arg.toCharArray())
{
@@ -117,7 +119,7 @@ public class CommandLineBuilder
escaped = (c == '\\');
buf.append(c);
}
-// buf.append('"');
+ // buf.append('"');
return buf.toString();
}
@@ -133,7 +135,7 @@ public class CommandLineBuilder
{
buf.append(' ');
}
- buf.append(arg);
+ buf.append(quote(arg));
delim = true;
}
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java
index ae33b07536..fd4b280014 100644
--- a/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java
@@ -18,22 +18,29 @@
package org.eclipse.jetty.start;
-import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.is;
+
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
public class CommandLineBuilderTest
{
- @Test
- public void testSimpleCommandline()
+ private CommandLineBuilder cmd = new CommandLineBuilder("java");
+
+ @Before
+ public void setUp()
{
- CommandLineBuilder cmd = new CommandLineBuilder("java");
cmd.addEqualsArg("-Djava.io.tmpdir","/home/java/temp dir/");
cmd.addArg("--version");
-
- Assert.assertThat(cmd.toString(), is("java -Djava.io.tmpdir=/home/java/temp\\ dir/ --version"));
}
-
+
+ @Test
+ public void testSimpleCommandline()
+ {
+ Assert.assertThat(cmd.toString(),is("java -Djava.io.tmpdir=/home/java/temp\\ dir/ --version"));
+ }
+
@Test
public void testQuotingSimple()
{
@@ -52,6 +59,12 @@ public class CommandLineBuilderTest
assertQuoting("/opt/jetty 7 \"special\"/home","/opt/jetty\\ 7\\ \\\"special\\\"/home");
}
+ @Test
+ public void testToStringIsQuotedEvenIfArgsAreNotQuotedForProcessBuilder()
+ {
+ System.out.println(cmd.toString());
+ }
+
private void assertQuoting(String raw, String expected)
{
String actual = CommandLineBuilder.quote(raw);
diff --git a/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java b/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java
index 68989ffeed..a713f7f60a 100644
--- a/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java
+++ b/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java
@@ -18,10 +18,6 @@
package org.eclipse.jetty.start;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertEquals;
-
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
@@ -30,10 +26,16 @@ import java.util.List;
import java.util.Vector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
/* ------------------------------------------------------------ */
/**
*/
@@ -101,14 +103,24 @@ public class MainTest
Classpath classpath = nastyWayToCreateAClasspathObject("/jetty/home with spaces/");
CommandLineBuilder cmd = main.buildCommandLine(classpath,xmls);
- Assert.assertThat("CommandLineBuilder shouldn't be null",cmd,notNullValue());
- String commandLine = cmd.toString();
- Assert.assertThat("CommandLine shouldn't be null",commandLine,notNullValue());
- Assert.assertThat("Classpath should be correctly quoted and match expected value",commandLine,
- containsString("-cp /jetty/home with spaces/somejar.jar:/jetty/home with spaces/someotherjar.jar"));
- Assert.assertThat("CommandLine should contain jvmArgs",commandLine,containsString("--exec -Xms1024m -Xmx1024m"));
- Assert.assertThat("CommandLine should contain xmls",commandLine,containsString("jetty.xml jetty-jmx.xml jetty-logging.xml"));
+ assertThat("CommandLineBuilder shouldn't be null",cmd,notNullValue());
+
+ List<String> commandArgs = cmd.getArgs();
+ assertThat("commandArgs should contain 11 elements",commandArgs.size(),equalTo(11));
+ assertThat("args does not contain -cp",commandArgs,hasItems("-cp"));
+ assertThat("Classpath should be correctly quoted and match expected value",commandArgs,
+ hasItems("/jetty/home with spaces/somejar.jar:/jetty/home with spaces/someotherjar.jar"));
+ assertThat("args does not contain --exec",commandArgs,hasItems("--exec"));
+ assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xms1024m"));
+ assertThat("CommandLine should contain jvmArgs", commandArgs, hasItems("-Xmx1024m"));
+ assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty.xml"));
+ assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-jmx.xml"));
+ assertThat("CommandLine should contain xmls", commandArgs, hasItems("jetty-logging.xml"));
+ String commandLine = cmd.toString();
+ assertThat("cmd.toString() should be properly escaped",commandLine,containsString("-cp /jetty/home\\ with\\ " +
+ "spaces/somejar.jar:/jetty/home\\ with\\ spaces/someotherjar.jar"));
+ assertThat("cmd.toString() doesn't contain xml config files",commandLine,containsString(" jetty.xml jetty-jmx.xml jetty-logging.xml"));
}
private Classpath nastyWayToCreateAClasspathObject(String jettyHome) throws NoSuchFieldException, IllegalAccessException

Back to the top